一個項目需求要求返回值為JSON格式,且大多數(shù)字段是首字母大寫,還有些是類似N_TX這樣的格式,在輸出這樣的結(jié)果時遇到了問題,由于時間緊,就直接拷貝需要的結(jié)果字段建立JavaBean類,本以為最后直接調(diào)用JSON.toString(obj)返回結(jié)果即可,沒想到返回值中自動將首字母變小寫。查看fastjson源碼發(fā)現(xiàn)關(guān)鍵在下面一段
public static List<FieldInfo> computeGetters(Class<?> clazz, Map<String, String> aliasMap, boolean sorted) {
String propertyName;
if (Character.isUpperCase(c3)) {
if (compatibleWithJavaBean) {
propertyName = Introspector.decapitalize(methodName.substring(3));
} else {
propertyName = Character.toLowerCase(methodName.charAt(3)) + methodName.substring(4);
}
} else if (c3 == '_') {
propertyName = methodName.substring(4);
} else if (c3 == 'f') {
propertyName = methodName.substring(3);
} else {
continue;
}
}
// 在compatibleWithJavaBean為false時直接get對應(yīng)屬性首字母小寫,考慮將compatibleWithJavaBean初始化為true,發(fā)現(xiàn)
public static String decapitalize(String name) {
if (name == null || name.length() == 0) {
return name;
}
if (name.length() > 1 && Character.isUpperCase(name.charAt(1)) &&
Character.isUpperCase(name.charAt(0))) {
return name;
}
char chars[] = name.toCharArray();
chars[0] = Character.toLowerCase(chars[0]);
return new String(chars);
}
//只能在連續(xù)的大寫字母情況下才不進行首字母變小寫操作。故此方法也不滿足要求。
根本原因: java 的內(nèi)省機制
內(nèi)省(Introspector)是Java 語言對Bean類屬性、事件的一種缺省處理方法。例如類 A 中有屬性 name, 那我們可以通過 getName,setName 來得到其值或者設(shè)置新的值。通過 getName/setName 來訪問 name 屬性,這就是默認的規(guī)則。 一個類被當作javaBean使用時,JavaBean的屬性是根據(jù)方法名推斷出來的,它根本看不到j(luò)ava類內(nèi)部的成員變量,通過去掉set方法前綴,然后取剩余部分,如果剩余部分的第二個字母是小寫的,則把剩余部分的首字母改成小寫。參考:http://blog.csdn.net/hahalzb/article/details/5972421
如何解決
1、直接將bean對象中的屬性改為public,屬性名命名為首字母大寫,比如{"Name":"nomouse","Age":12},定義相應(yīng)的bean為:熟悉為public,不需要定義get方法
public class User {
public String Name;
public int Age;
}
2、第一種方法不符合Java的命名規(guī)范,可以用第二種方法,在屬性上添加注解:
public class User {
@JSONField (value = "Name")
private String name;
@JSONField(value = "Age")
private int age;
}
3、自己利用反射寫Object2Json和list2Json方法,只要能對簡單的JavaBean類處理即可。
DisableCheckSpecialChar:一個對象的字符串屬性中如果有特殊字符如雙引號,將會在轉(zhuǎn)成json時帶有反斜杠轉(zhuǎn)移符。如果不需要轉(zhuǎn)義,可以使用這個屬性。默認為false
QuoteFieldNames———-輸出key時是否使用雙引號,默認為true
WriteMapNullValue——–是否輸出值為null的字段,默認為false
WriteNullNumberAsZero—-數(shù)值字段如果為null,輸出為0,而非null
WriteNullListAsEmpty—–List字段如果為null,輸出為[],而非null
WriteNullStringAsEmpty—字符類型字段如果為null,輸出為”“,而非null
WriteNullBooleanAsFalse–Boolean字段如果為null,輸出為false,而非null