fastJson過濾器:
fastjson 過濾不需要的字段或者只要某些字段
/*
* 第一種:在對象響應字段前加注解值桩,這樣生成的json也不包含該字段摆霉。
* @JSONField(serialize=false)
* private String name;
*/
/*
* 第二種:在對象對應字段前面加transient,表示該字段不用序列化颠毙,即在生成json的時候就不會包含該字段了斯入。
* private transient String name;
*/
/*
* 第三種:使用fastjson的攔截器
* PropertyFilter profilter = new PropertyFilter(){
@Override
public boolean apply(Object object, String name, Object value) {
if(name.equalsIgnoreCase("last")){
//false表示last字段將被排除在外
return false;
}
return true;
}
};
json = JSON.toJSONString(user, profilter);
System.out.println(json);
*/
/*
* 第四種,直接填寫屬性
* SimplePropertyPreFilter filter = new SimplePropertyPreFilter(TTown.class, "id","townname");
response.getWriter().write(JSONObject.toJSONString(townList,filter));
*/
工具組同學在做熱修復時發(fā)現(xiàn)一種robust不能兼容的情況蛀蜜。就是對對象進行序列化刻两,這個對象會根據(jù)類的字段和方法自動生成serialVersionUID, robust插入代碼后serialVersionUID變掉了滴某,導致反序列化失敗磅摹。
因為這個整理了下相關文檔。
文檔:
既然如此霎奢,那沒有定義serialVersionUID的那些對象户誓,被存入的本地文件,新版本該類改變了類變量幕侠,那讀取的舊緩存的文件還能正確恢復嗎帝美,新添加的字段被恢復成默認值還是直接報InvalidClassException的異常?
那如果是通過fastJson的jsonString存儲和恢復呢晤硕?因為這種方式是將對象編程鍵值對的json格式悼潭,不是嚴格意義上序列化,github的說明上也說了舞箍,只要是符合JavaBean規(guī)范的都可以舰褪,不用非要serialVerionUID。demo很簡單就可以證明疏橄。
具體詳細的解釋可以參考:Java序列化
平時定義的bean都是json對應的占拍,看樣子不怎么符合JavaBean標準。而且如有有復雜對象的拷貝需求,fastJson的方法看起來是最方便最快的晃酒。
正好需求中碰到相冊數(shù)據(jù)的深拷貝表牢,用的是序列化的方法做的。想到能不能改成json解析的方法掖疮,然后就剛好遇到了個問題初茶。
- 序列化方法實現(xiàn):單個對象clone,列表要在外層循環(huán)調用clone方法
// serializable object
public static GalleryItem deepCloneGalleryItem(GalleryItem in) {
try {
long ss= System.currentTimeMillis();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(in);
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bais);
LogUtil.v("InLog", "success deepCloneGalleryItem= " + (System.currentTimeMillis() - ss)) ;
return (GalleryItem) ois.readObject();
} catch (IOException e) {
e.printStackTrace();
LogUtil.e("InLog", "IOException deepCloneGalleryItem");
return null;
} catch (ClassNotFoundException e) {
e.printStackTrace();
LogUtil.e("InLog", "ClassNotFoundException deepCloneGalleryItem");
return null;
}
}
@Override
public void notifyPrepareDataList(List<GalleryItem> list) {
for (GalleryItem item : list) {
it = ListUtil.deepCloneGalleryItem(item);
}
}
- Json轉化方法實現(xiàn):單個對象clone或直接整個列表clone
public static void cloneJson(GalleryItem in){
long ss = System.currentTimeMillis();
String json = JSON.toJSONString(in);
GalleryItem item = JSON.parseObject(json, GalleryItem.class);
LogUtil.v("InLog", "cloneJson cost " + (System.currentTimeMillis() - ss));
LogUtil.v("InLog", "cloneJson in " + in.hashCode() + ",item is " + item.hashCode());
}
public static void cloneJson(List<GalleryItem> in){
long ss = System.currentTimeMillis();
String json = JSON.toJSONString(in);
List<GalleryItem> item = JSON.parseArray(json, GalleryItem.class);
LogUtil.d("InLog", "cloneJson cost " + (System.currentTimeMillis() - ss));
}
@Override
public void notifyPrepareDataList(List<GalleryItem> list) {
ListUtil.cloneJson(list);
}
該對象的以上兩種方法浊闪,json轉換的方法并沒有更快恼布。1000個對象時間差不多。
使用的fastJson是android版本:'com.alibaba:fastjson:1.1.51.android'搁宾,因為GalleryItem有個long型字段復寫get方法時返回了String折汞,導致JSON.toJSONString(in);一直報錯:
Error:
com.alibaba.fastjson.JSONException: write javaBean error
at com.alibaba.fastjson.serializer.JavaBeanSerializer.write(JavaBeanSerializer.java:600)
at com.alibaba.fastjson.serializer.JSONSerializer.write(JSONSerializer.java:262)
at com.alibaba.fastjson.JSON.toJSONString(JSON.java:607)
at com.alibaba.fastjson.JSON.toJSONString(JSON.java:334)
..............................................
.....
Caused by: java.lang.ClassCastException: java.lang.Long cannot be cast to java.lang.String
at com.alibaba.fastjson.serializer.JavaBeanSerializer.write(JavaBeanSerializer.java:526)
... 21 more
被這個問題困擾好久,app os:死前我都提示線索了盖腿,你怎么還沒破案啊爽待。
原因就是get方法返回型和定義的不一樣了。所以這種在bean里直接改變返回型的做法不適合在fastJson里用翩腐。
public long duration;
public String getDuration() {
try {
return formatTimeWithMin(duration);
} catch (NumberFormatException e) {
return "0:00";
}
}
但是在使用新的版本compile com.alibaba:fastjson:1.1.67.android鸟款,以上不會出錯。應該是修復了該問題茂卦,但是在JonsString解析成對象時還是會報類型轉換的異常導致轉換不成功何什。所以還是在使用時注意這種情況的轉換。
附送其他使用注意事項fastjson使用過程中的坑
以及一個容易被忽視的原因分析等龙。
JVM源碼分析之不保證順序的Class.getMethods
當然開源庫在更新处渣,新的版本會有不同的優(yōu)化,注意差異蛛砰。