public class Demo {
private Boolean isHot;
private Boolean isQuick;
public Boolean getHot() {
return isHot;
}
public void setHot(Boolean hot) {
isHot = hot;
}
public Boolean getQuick() {
return isQuick;
}
public void setQuick(Boolean quick) {
isQuick = quick;
}
}
複製代碼
例如上面一個bean,getset方法均爲idea自動生成的(Idea 2020.1),Fastjson序列化後的結果爲java
{
"hot":true,
"quick":true
}
複製代碼
咱們其實指望的是json
{
"isHot":true,
"isQuick":true
}
複製代碼
修改get方法爲getIsXXX
public Boolean getHot()
->public Boolean getIsHot()
api
去掉getset方法使用lombok,若是公司容許的話markdown
修改idea默認模板app
#set($paramName = $helper.getParamName($field, $project))
#if($field.modifierStatic)
static ##
#end
$field.type ##
#set($name = $StringUtil.capitalizeWithJavaBeanConvention($StringUtil.sanitizeJavaIdentifier($helper.getPropertyName($field, $project))))
#if ($field.name == $paramName)
get##
#else
getIs##
#end
${name}() {
return this.##
$field.name;
}
複製代碼
不要以is開頭,加入公司的代碼規範,《Java開發手冊(泰山版)》中也提到了框架
【強制】POJO 類中的任何布爾類型的變量,都不要加 is 前綴,不然部分框架解析會引發序列 化錯誤。ide
下面咱們看一下Fastjson源碼源碼分析
public static List<FieldInfo> computeGetters(Class<?> clazz, // JSONType jsonType, // Map<String,String> aliasMap, // Map<String,Field> fieldCacheMap, // boolean sorted, // PropertyNamingStrategy propertyNamingStrategy // ){
Map<String,FieldInfo> fieldInfoMap = new LinkedHashMap<String,FieldInfo>();
boolean kotlin = TypeUtils.isKotlin(clazz);
// for kotlin
Constructor[] constructors = null;
Annotation[][] paramAnnotationArrays = null;
String[] paramNames = null;
short[] paramNameMapping = null;
Method[] methods = clazz.getMethods();
for(Method method : methods){
.....此處省略
//主要是這裏
if(methodName.startsWith("get")){
if(methodName.length() < 4){
continue;
}
if(methodName.equals("getClass")){
continue;
}
if(methodName.equals("getDeclaringClass") && clazz.isEnum()){
continue;
}
char c3 = methodName.charAt(3);
String propertyName;
Field field = null;
if(Character.isUpperCase(c3) //
|| c3 > 512 // for unicode method name
){
if(compatibleWithJavaBean){
//根據get方法取值
propertyName = decapitalize(methodName.substring(3));
} else{
propertyName = Character.toLowerCase(methodName.charAt(3)) + methodName.substring(4);
}
propertyName = getPropertyNameByCompatibleFieldName(fieldCacheMap, methodName, propertyName, 3);
}
......再度省略
fieldInfoMap.put(propertyName, fieldInfo);
}
}
Field[] fields = clazz.getFields();
computeFields(clazz, aliasMap, propertyNamingStrategy, fieldInfoMap, fields);
return getFieldInfos(clazz, sorted, fieldInfoMap);
}
複製代碼
後面就基本上以這個名稱爲準了。ui
這個writer是經過動態生成的一個bean,因此代碼沒法追蹤,可是它強轉了下
return (JavaBeanSerializer) instance;
因此咱們能夠看下JavaBeanSerializer::write
方法看下是如何把bean
轉成String的
this
protected void write(JSONSerializer serializer, // Object object, // Object fieldName, // Type fieldType, // int features, boolean unwrapped ) throws IOException {
SerializeWriter out = serializer.out;
if (object == null) {
out.writeNull();
return;
}
if (writeReference(serializer, object, features)) {
return;
}
final FieldSerializer[] getters;
//獲取咱們剛剛解析的成員變量c h
if (out.sortField) {
getters = this.sortedGetters;
} else {
getters = this.getters;
}
SerialContext parent = serializer.context;
if (!this.beanInfo.beanType.isEnum()) {
serializer.setContext(parent, object, fieldName, this.beanInfo.features, features);
}
final boolean writeAsArray = isWriteAsArray(serializer, features);
FieldSerializer errorFieldSerializer = null;
try {
final char startSeperator = writeAsArray ? '[' : '{';
final char endSeperator = writeAsArray ? ']' : '}';
if (!unwrapped) {
//全程添加到out裏面,最後toJSONString輸出的也是out
out.append(startSeperator);
}
if (getters.length > 0 && out.isEnabled(SerializerFeature.PrettyFormat)) {
serializer.incrementIndent();
serializer.println();
}
boolean commaFlag = false;
if ((this.beanInfo.features & SerializerFeature.WriteClassName.mask) != 0
||(features & SerializerFeature.WriteClassName.mask) != 0
|| serializer.isWriteClassName(fieldType, object)) {
Class<?> objClass = object.getClass();
final Type type;
if (objClass != fieldType && fieldType instanceof WildcardType) {
type = TypeUtils.getClass(fieldType);
} else {
type = fieldType;
}
if (objClass != type) {
writeClassName(serializer, beanInfo.typeKey, object);
commaFlag = true;
}
}
char seperator = commaFlag ? ',' : '\0';
final boolean writeClassName = out.isEnabled(SerializerFeature.WriteClassName);
char newSeperator = this.writeBefore(serializer, object, seperator);
commaFlag = newSeperator == ',';
final boolean skipTransient = out.isEnabled(SerializerFeature.SkipTransientField);
final boolean ignoreNonFieldGetter = out.isEnabled(SerializerFeature.IgnoreNonFieldGetter);
for (int i = 0; i < getters.length; ++i) {
.....字符串拼接
}
this.writeAfter(serializer, object, commaFlag ? ',' : '\0');
if (getters.length > 0 && out.isEnabled(SerializerFeature.PrettyFormat)) {
serializer.decrementIdent();
serializer.println();
}
if (!unwrapped) {
//全程添加進out裏面
out.append(endSeperator);
}
} catch (Exception e) {
.....處理異常,忽略
} finally {
serializer.context = parent;
}
}
複製代碼