20171122-fastJson铲掐、序列化、深拷貝

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解析的方法掖疮,然后就剛好遇到了個問題初茶。

  1. 序列化方法實現(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);
        }
    }
  1. 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解析成對象時還是會報類型轉換的異常導致轉換不成功何什。所以還是在使用時注意這種情況的轉換。

image

附送其他使用注意事項fastjson使用過程中的坑

以及一個容易被忽視的原因分析等龙。
JVM源碼分析之不保證順序的Class.getMethods

當然開源庫在更新处渣,新的版本會有不同的優(yōu)化,注意差異蛛砰。

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末罐栈,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子泥畅,更是在濱河造成了極大的恐慌荠诬,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,743評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件位仁,死亡現(xiàn)場離奇詭異柑贞,居然都是意外死亡,警方通過查閱死者的電腦和手機障癌,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,296評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來辩尊,“玉大人涛浙,你說我怎么就攤上這事。” “怎么了轿亮?”我有些...
    開封第一講書人閱讀 157,285評論 0 348
  • 文/不壞的土叔 我叫張陵疮薇,是天一觀的道長。 經常有香客問我我注,道長按咒,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,485評論 1 283
  • 正文 為了忘掉前任但骨,我火速辦了婚禮励七,結果婚禮上,老公的妹妹穿的比我還像新娘奔缠。我一直安慰自己掠抬,他們只是感情好,可當我...
    茶點故事閱讀 65,581評論 6 386
  • 文/花漫 我一把揭開白布校哎。 她就那樣靜靜地躺著两波,像睡著了一般。 火紅的嫁衣襯著肌膚如雪闷哆。 梳的紋絲不亂的頭發(fā)上腰奋,一...
    開封第一講書人閱讀 49,821評論 1 290
  • 那天,我揣著相機與錄音抱怔,去河邊找鬼劣坊。 笑死,一個胖子當著我的面吹牛野蝇,可吹牛的內容都是我干的讼稚。 我是一名探鬼主播,決...
    沈念sama閱讀 38,960評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼绕沈,長吁一口氣:“原來是場噩夢啊……” “哼锐想!你這毒婦竟也來了?” 一聲冷哼從身側響起乍狐,我...
    開封第一講書人閱讀 37,719評論 0 266
  • 序言:老撾萬榮一對情侶失蹤赠摇,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后浅蚪,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體藕帜,經...
    沈念sama閱讀 44,186評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,516評論 2 327
  • 正文 我和宋清朗相戀三年惜傲,在試婚紗的時候發(fā)現(xiàn)自己被綠了洽故。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,650評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡盗誊,死狀恐怖时甚,靈堂內的尸體忽然破棺而出隘弊,到底是詐尸還是另有隱情,我是刑警寧澤荒适,帶...
    沈念sama閱讀 34,329評論 4 330
  • 正文 年R本政府宣布梨熙,位于F島的核電站,受9級特大地震影響刀诬,放射性物質發(fā)生泄漏咽扇。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,936評論 3 313
  • 文/蒙蒙 一陕壹、第九天 我趴在偏房一處隱蔽的房頂上張望质欲。 院中可真熱鬧,春花似錦帐要、人聲如沸把敞。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,757評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽奋早。三九已至,卻和暖如春赠橙,著一層夾襖步出監(jiān)牢的瞬間耽装,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,991評論 1 266
  • 我被黑心中介騙來泰國打工期揪, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留掉奄,地道東北人。 一個月前我還...
    沈念sama閱讀 46,370評論 2 360
  • 正文 我出身青樓凤薛,卻偏偏與公主長得像姓建,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子缤苫,可洞房花燭夜當晚...
    茶點故事閱讀 43,527評論 2 349

推薦閱讀更多精彩內容

  • JAVA序列化機制的深入研究 對象序列化的最主要的用處就是在傳遞,和保存對象(object)的時候,保證對象的完整...
    時待吾閱讀 10,842評論 0 24
  • FastJson是一個近幾年非常熱門的第三方java庫速兔,它以它強大的功能和出色的性能表現(xiàn)而廣為人知。那么活玲,究竟為何...
    月強閱讀 14,592評論 0 15
  • Spring Cloud為開發(fā)人員提供了快速構建分布式系統(tǒng)中一些常見模式的工具(例如配置管理涣狗,服務發(fā)現(xiàn),斷路器舒憾,智...
    卡卡羅2017閱讀 134,633評論 18 139
  • 我輕輕的來到這個未知的世界窟赏,我又悄悄的走了措译,不帶走一片云彩。 人的一生總就是空歡喜一場饰序,生不帶來,死不帶去规哪。 人生...
    嫻來吳侍閱讀 994評論 0 0
  • 人之初诉稍,性本善蝠嘉。善良其實本就是人本性的一種淳樸的流露。雖然可能會在社會大環(huán)境下有“流俗眾杯巨,仁者稀”的危險蚤告,但不...
    青青草木牛牛閱讀 635評論 5 3