jackson

今天在其他項目里面看到有人用jackson,就試著用了一下切距,并做點筆記趾徽。

一奶陈、jackson簡介

解析原理:基于事件驅動,與GSON相同附较,先創(chuàng)建一個對應于JSON數(shù)據(jù)的JavaBean類就可以通過簡單的操作解析出所需JSON數(shù)據(jù)吃粒。但和Gson解析不同的是,GSON可按需解析拒课,即創(chuàng)建的JavaBean類不一定完全涵蓋所要解析的JSON數(shù)據(jù)徐勃,按需創(chuàng)建屬性事示,但Jackson解析對應的JavaBean必須把Json數(shù)據(jù)里面的所有key都有所對應,即必須把JSON內的數(shù)據(jù)所有解析出來僻肖,無法按需解析肖爵。但Jackson的解析速度和效率都要比GSON高

二、Jackson臀脏、JSON-lib劝堪、Gson的比較

網(wǎng)上偷來一張圖作為對比Jackson、JSON-lib揉稚、Gson的解析速率

Paste_Image.png

測試總結:

1秒啦、顯而易見,無論是哪種形式的轉換搀玖,Jackson > Gson > Json-lib余境。
Jackson的處理能力甚至高出Json-lib有10倍左右
2、JSON-lib似乎已經停止更新灌诅,最新的版本也是基于JDK15芳来,而Jackson的社區(qū)則較為活躍;
3猜拾、在測試性能的同時即舌,又以人肉方式對這三個類庫轉換的正確性 進行了檢查 ,三者均達100%正確 挎袜;
4侥涵、JSON-lib在轉換諸如Date類型時較為累贅,如以下是兩者的轉換結果:
JSON-lib:
{"brithday":{"date":17,"day":2,"hours":9,"minutes":24,"month":7,"seconds":26,"time":1282008266398,"timezoneOffset":-480,"year":110}}
Jackson:
{"brithday":1282008123101}
5宋雏、JSON-lib依賴commons系列的包及 ezmorph包共 5個,而Jackson除自身的以外只依賴于commons-logging
6务豺、Jackson提供完整基于節(jié)點的Tree Model磨总,以及完整的OJM數(shù)據(jù)綁定功能。

三笼沥、jackson的基本使用
1蚪燕、導入項目
compile 'com.squareup.retrofit2:converter-jackson:2.2.0'

如果這里有沖突報錯,這添加下面這段話

android {
    ...
    }

    packagingOptions {
        exclude 'META-INF/services/javax.annotation.processing.Processor'
        exclude 'META-INF/LICENSE'
        exclude 'META-INF/NOTICE'
    }
}
2奔浅、DEMO
package com.ycxc.template.bean;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;

import java.util.List;

/**
 * Fuction: 網(wǎng)易新聞詳情<p>
 */
@JsonIgnoreProperties(ignoreUnknown = true)
public class NeteastNewsSummary {
    @JsonProperty("postid")
    public String postid;
    @JsonProperty("hasCover")
    public boolean hasCover;
    @JsonProperty("hasHead")
    public int hasHead;
    @JsonProperty("replyCount")
    public int replyCount;
    @JsonProperty("hasImg")
    public int hasImg;
    @JsonProperty("digest")
    public String digest;
    @JsonProperty("hasIcon")
    public boolean hasIcon;
    @JsonProperty("docid")
    public String docid;
    @JsonProperty("title")
    public String title;
    @JsonProperty("order")
    public int order;
    @JsonProperty("priority")
    public int priority;
    @JsonProperty("lmodify")
    public String lmodify;
    @JsonProperty("boardid")
    public String boardid;
    @JsonProperty("photosetID")
    public String photosetID;
    @JsonProperty("template")
    public String template;
    @JsonProperty("votecount")
    public int votecount;
    @JsonProperty("skipID")
    public String skipID;
    @JsonProperty("alias")
    public String alias;
    @JsonProperty("skipType")
    public String skipType;
    @JsonProperty("cid")
    public String cid;
    @JsonProperty("hasAD")
    public int hasAD;
    @JsonProperty("imgsrc")
    public String imgsrc;
    @JsonProperty("tname")
    public String tname;
    @JsonProperty("ename")
    public String ename;
    @JsonProperty("ptime")
    public String ptime;
    /**
     * title : 哈薩克斯坦中亞在建第1高樓爆炸起火
     * tag : photoset
     * imgsrc : http://img5.cache.netease.com/3g/2016/2/13/2016021318005710210.jpg
     * subtitle :
     * url : 00AN0001|110630
     */

    @JsonProperty("ads")
    public List<AdsEntity> ads;
    /**
     * imgsrc : http://img5.cache.netease.com/3g/2016/2/13/201602131446132dc50.jpg
     */

    @JsonProperty("imgextra")
    public List<ImgextraEntity> imgextra;

    @JsonIgnoreProperties(ignoreUnknown = true)
    public static class AdsEntity {
        @JsonProperty("title")
        public String title;
        @JsonProperty("tag")
        public String tag;
        @JsonProperty("imgsrc")
        public String imgsrc;
        @JsonProperty("subtitle")
        public String subtitle;
        @JsonProperty("url")
        public String url;
    }

    @JsonIgnoreProperties(ignoreUnknown = true)
    public static class ImgextraEntity {
        @JsonProperty("imgsrc")
        public String imgsrc;
    }
}

四馆纳、相關屬性介紹
1 排除屬性

@JsonIgnore,一般標記在屬性或方法上的注解汹桦。序列化與反序列化時忽略被該注解修飾的成員鲁驶。
@JsonIgnoreProperties,如果是代理類舞骆,由于無法標記在屬性或方法上钥弯,所以径荔,可以標記在類聲明上;也作用于反序列化時的字段解析脆霎;

@JsonIgnoreProperties({"extra"})
類注解总处。在反序列化 json 數(shù)據(jù)時能夠忽略注解參數(shù)中對應的 json keys。

@JsonIgnoreProperties(ignoreUnknown = true)
//Jackson解析JSON數(shù)據(jù)時睛蛛,忽略未知的字段鹦马。(如果不設置,當JSON字段和bean字段不匹配時忆肾,會拋出異常)
2 屬性別名

@JsonProperty荸频,序列化/反序列化都有效;

3 屬性排序

@JsonPropertyOrder难菌,注釋在類聲明中试溯;

4 屬性格式轉換

使用自定義序列化/反序列化來處理;
@JsonSerialize郊酒,序列化遇绞;
@JsonDeserialize,反序列化燎窘;

注意:在使用hibernate的時候摹闽,查詢數(shù)據(jù)庫后產生的實體類是個代理類,這時候轉換JSON會報錯褐健;

解決方法有兩種:
1)設置FAIL_ON_EMPTY_BEANS屬性付鹿,告訴Jackson空對象不要拋異常;
mapper.disable(SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS);
2)使用@JsonIgnoreProperties注解
在實體類聲明處加上@JsonIgnoreProperties(value = {"hibernateLazyInitializer", "handler"})注解蚜迅;
建議使用@JsonIgnoreProperties注解舵匾,這樣生成的JSON中不會產生多余的字段;

@JsonSerialize(using = JacksonUtil.JsonLocalDateSerializer.class)
屬性注解谁不。需要使用自定義序列化與反序列化解析器時坐梯,使用該注解修飾類成員變量。
5 父/子關聯(lián)

@JsonManagedReference刹帕,放在父親類中吵血;
@JsonBackReference,放在孩子類中偷溺;

6 去掉包裝

@JsonUnwrapped蹋辅,意思如下:

Ability to map JSON like
{
"name" : "home",
"latitude" : 127,
"longitude" : 345
}
to classes defined as:
class Place {
public String name;

@JsonUnwrapped
public Location location;
}

class Location {
public int latitude, longitude;
}

五、JacksonUtil

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.type.CollectionType;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;

import java.io.IOException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Map;


/**
 * XML,JSON處理工具類
 * 依靠jackson提供pojo2json/xml轉換
 *
 * @author HaiJia
 */

final public class JacksonUtil {


    private static ObjectMapper objectMapper = new ObjectMapper();

    private static ObjectMapper xmlMapper = new XmlMapper();


    /**
     * 防止反射調用構造器創(chuàng)建對象
     */
    private JacksonUtil() {
        throw new AssertionError();
    }

    /**
     * 自定義日期序列化處理類
     * LocalDateTime
     * jdk8 support
     */
    public static class JsonLocalDateTimeSerializer extends JsonSerializer<LocalDateTime> {


        @Override
        public void serialize(LocalDateTime localDateTime, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
            String localdateTimeStr = localDateTime.format(DateTimeFormatter.ISO_DATE_TIME);
            jsonGenerator.writeString(localdateTimeStr);
        }
    }

    /**
     * 自定義日期序列化處理類
     * LocalDateTime
     * jdk8 support
     */
    public static class JsonLocalDateTimeDeserializer extends JsonDeserializer<LocalDateTime> {


        @Override
        public LocalDateTime deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
            String str = jsonParser.getText().trim();
            return LocalDateTime.parse(str, DateTimeFormatter.ISO_DATE_TIME);
        }
    }

    /**
     * 自定義日期反序列化處理類
     * LocalDate
     * jdk8 support
     */
    public static class JsonLocalDateDeserializer extends JsonDeserializer<LocalDate> {

        @Override
        public LocalDate deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
            String str = jsonParser.getText().trim();
            return LocalDate.parse(str, DateTimeFormatter.ISO_DATE);
        }
    }

    /**
     * 自定義日期序列化類
     * LocalDate
     * jdk8 support
     */
    public static class JsonLocalDateSerializer extends JsonSerializer<LocalDate> {


        @Override
        public void serialize(LocalDate localDate, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
            String localdateStr = localDate.format(DateTimeFormatter.ISO_DATE);
            jsonGenerator.writeString(localdateStr);
        }
    }

    /**
     * json數(shù)據(jù)轉pojo
     *
     * @param jsonStr json字符串
     * @param cls     映射類型
     * @param <T>     推導類型
     * @return 推導類型json對象
     */
    public static <T> T json2Pojo(String jsonStr, Class<T> cls) {
        T object = null;
        try {
            object = objectMapper.readValue(jsonStr, cls);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return object;
    }


    /**
     * json數(shù)據(jù)轉PojoList
     *
     * @param jsonStr json數(shù)據(jù)
     * @param cls     類型
     * @param <T>     推導類型
     * @return pojoList
     */
    public static <T> List<T> jsonArray2PojoList(String jsonStr, Class<T> cls) {
        List<T> pojoList = null;
        try {
            CollectionType listType = objectMapper.getTypeFactory().constructCollectionType(List.class, cls);
            pojoList = objectMapper.readValue(jsonStr, listType);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return pojoList;
    }


    /**
     * pojo轉json
     *
     * @param obj pojo
     * @return json字符串
     */
    public static String pojo2Json(Object obj) {
        String jsonStr = "";
        try {
            jsonStr = objectMapper.writeValueAsString(obj);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        return jsonStr;
    }

    /**
     * json轉listMap
     *
     * @param jsonArray jsonArray字符串
     * @return Listmap對象
     */
    public static List<Map<String, Object>> jsonArray2ListMap(String jsonArray) {
        List<Map<String, Object>> convertedListMap = null;
        try {
            convertedListMap = objectMapper.readValue(jsonArray, new TypeReference<List<Map<String, Object>>>() {
            });
        } catch (IOException e) {
            e.printStackTrace();
        }
        return convertedListMap;
    }

    /**
     * json轉map
     *
     * @param json json字符串
     * @return map對象
     */
    public static Map<String, Object> json2Map(String json) {
        Map<String, Object> convertedMap = null;
        try {
            convertedMap = objectMapper.readValue(json, new TypeReference<Map<String, Object>>() {
            });
        } catch (IOException e) {
            e.printStackTrace();
        }
        return convertedMap;
    }


    /**
     * listMap轉json
     *
     * @param listMap listMap
     * @return
     */
    public static String listMap2JsonArray(List<Map<String, Object>> listMap) {
        String jsonStr = "";
        try {
            jsonStr = objectMapper.writeValueAsString(listMap);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        return jsonStr;
    }


    /**
     * xml轉pojo
     *
     * @param xmlStr xml字符串
     * @param cls    映射對象
     * @param <T>    推導類型
     * @return pojo
     */
    public static <T> T xml2Pojo(String xmlStr, Class<T> cls) {
        T pojo = null;
        try {
            pojo = xmlMapper.readValue(xmlStr, cls);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return pojo;
    }

    /**
     * xml轉pojoList
     *
     * @param xmlStr xml字符串
     * @param cls    映射對象
     * @param <T>    推導類型
     * @return pojo
     */
    public static <T> List<T> xml2PojoList(String xmlStr, Class<T> cls) {
        CollectionType listType = objectMapper.getTypeFactory().constructCollectionType(List.class, cls);
        List<T> pojoList = null;
        try {
            pojoList = xmlMapper.readValue(xmlStr, listType);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return pojoList;
    }


    /**
     * pojo轉xml
     *
     * @param object
     */
    public static String pojo2Xml(Object object) {
        String xml = "";
        try {
            xml = xmlMapper.writeValueAsString(object);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        return xml;
    }


    /**
     * xml轉map
     *
     * @param xmlStr xml字符串
     * @return map對象
     */
    public static Map<String, Object> xml2Map(String xmlStr) {
        Map<String, Object> map = null;
        try {
            map = xmlMapper.readValue(xmlStr, new TypeReference<Map<String, Object>>() {
            });
        } catch (IOException e) {
            e.printStackTrace();
        }
        return map;
    }

    /**
     * xml轉ListMap
     *
     * @param xmlStr xml字符串
     * @return map對象
     */
    public static List<Map<String, Object>> xml2ListMap(String xmlStr) {
        List<Map<String, Object>> listMap = null;
        try {
            listMap = xmlMapper.readValue(xmlStr, new TypeReference<List<Map<String, Object>>>() {
            });
        } catch (IOException e) {
            e.printStackTrace();
        }
        return listMap;
    }

}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末挫掏,一起剝皮案震驚了整個濱河市侦另,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖淋肾,帶你破解...
    沈念sama閱讀 218,036評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件硫麻,死亡現(xiàn)場離奇詭異,居然都是意外死亡樊卓,警方通過查閱死者的電腦和手機拿愧,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,046評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來碌尔,“玉大人浇辜,你說我怎么就攤上這事⊥倨荩” “怎么了柳洋?”我有些...
    開封第一講書人閱讀 164,411評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長叹坦。 經常有香客問我熊镣,道長,這世上最難降的妖魔是什么募书? 我笑而不...
    開封第一講書人閱讀 58,622評論 1 293
  • 正文 為了忘掉前任绪囱,我火速辦了婚禮,結果婚禮上莹捡,老公的妹妹穿的比我還像新娘鬼吵。我一直安慰自己,他們只是感情好篮赢,可當我...
    茶點故事閱讀 67,661評論 6 392
  • 文/花漫 我一把揭開白布齿椅。 她就那樣靜靜地躺著,像睡著了一般启泣。 火紅的嫁衣襯著肌膚如雪涣脚。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,521評論 1 304
  • 那天寥茫,我揣著相機與錄音遣蚀,去河邊找鬼。 笑死坠敷,一個胖子當著我的面吹牛,可吹牛的內容都是我干的射富。 我是一名探鬼主播膝迎,決...
    沈念sama閱讀 40,288評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼胰耗!你這毒婦竟也來了限次?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,200評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎卖漫,沒想到半個月后费尽,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經...
    沈念sama閱讀 45,644評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡羊始,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,837評論 3 336
  • 正文 我和宋清朗相戀三年旱幼,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片突委。...
    茶點故事閱讀 39,953評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡柏卤,死狀恐怖,靈堂內的尸體忽然破棺而出匀油,到底是詐尸還是另有隱情缘缚,我是刑警寧澤,帶...
    沈念sama閱讀 35,673評論 5 346
  • 正文 年R本政府宣布敌蚜,位于F島的核電站桥滨,受9級特大地震影響,放射性物質發(fā)生泄漏弛车。R本人自食惡果不足惜齐媒,卻給世界環(huán)境...
    茶點故事閱讀 41,281評論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望帅韧。 院中可真熱鬧里初,春花似錦、人聲如沸忽舟。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,889評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽叮阅。三九已至刁品,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間浩姥,已是汗流浹背挑随。 一陣腳步聲響...
    開封第一講書人閱讀 33,011評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留勒叠,地道東北人兜挨。 一個月前我還...
    沈念sama閱讀 48,119評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像眯分,于是被迫代替她去往敵國和親拌汇。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,901評論 2 355

推薦閱讀更多精彩內容