jackson使用入門

jackson是java中最常用的json處理工具包之一淆珊,其他類似功能的包括gson和fastjson等。本文將簡單介紹jackson的基礎知識浴讯,以作為各位讀者未來使用的參考司倚。

三種使用方式

jackson有三種處理json的方式,分別為

  • data binding
  • tree model
  • streaming api

data binding

這種方式可以在json字符串和pojo對象之間直接進行轉換灼伤。比如說我們有一個json字符串

{"firstName":"dizzy","lastName":"dwarf"}

通過這種方式我們可以直接將其轉換成一個Person類的實例,其中firstName和lastName是Person類定義的兩個成員變量咪鲜。

ObjectMapper objectMapper = new ObjectMapper();
Person person = objectMapper.readValue(jsonStr, Person.class);

tree model

這種方式類似于xml的DOM解析狐赡,在json字符串和DOM樹之間進行轉換,DOM樹的節(jié)點是JsonNode類型疟丙。其優(yōu)點在于以統(tǒng)一的方式看待json字符串中的各個部分颖侄,使用起來更靈活。

ObjectMapper objectMapper = new ObjectMapper();
JsonNode root = objectMapper.readTree(jsonStr);
JsonNode firstName = root.path("firstName");

構建DOM樹

如何構建JsonNode的DOM樹呢享郊?JsonNode是抽象類览祖,需要使用ObjectNodeArrayNode等子類。

ObjectNode objectNode = objectMapper.createObjectNode();
ArrayNode arrayNode = objectMapper.createArrayNode();

streaming api

這種方式類似于xml的SAX解析炊琉,每次處理一個事件展蒂,或者這里叫token更合適。

streaming api反序列化

反序列化用的是JsonParser苔咪,它的使用方式和迭代器非常相似锰悼。你每次處理的都是一個token,比如說在上面這個json字符串中团赏,包括{箕般、firstName、dizzy舔清、lastName隘世、dwarf、}等6個token鸠踪,通過調用nextToken方法可以獲得下一個token丙者。

streaming api序列化

序列化用的JsonGenerator,它的方法都非常直觀营密,比如說writeStartObject械媒、writeStringFieldwriteEndObject等,這里就不具體介紹了纷捞。

注解

通過注解可以定制jackson的各種特性痢虹,這里只介紹最常用的幾個。

序列化注解

  • @JsonGetter
    注解在方法上主儡,將方法返回的值作為字段序列化的值
public class Person {
    private String firstName;

    @JsonGetter("firstName")
    public String getFirstName() {
        return firstName + "_modified";
    }
    // 省略了setter方法
}

這樣一個firstName為"dizzy"的Person序列化后就變成了

{"firstName":"dizzy_modified"}
  • @JsonSerialize
    注解在成員變量上奖唯,使用指定的JsonSerializer實現(xiàn)類來序列化這個字段,這個實現(xiàn)類最關鍵的是serialize方法糜值,這個方法會為你提供JsonGenerator對象作為參數(shù)丰捷,讓你可以通過它來構建序列化后的值。
  • @JsonValue
    注解在方法上寂汇,將方法返回的值作為整個對象序列化的結果病往。

反序列化注解

  • @JsonSetter
    @JsonGetter的逆過程
  • @JsonDeserialize
    @JsonSerialize的逆過程
  • @JsonAlias
    默認情況下java對象中的成員變量名和json字符串的字段名是一對一關系的,但是可能存在這樣一種情況骄瓣。比如firstName這個成員變量停巷,可能json字符串有不同的來源,有的地方這個字段叫firstName榕栏,另外一些地方傳的字段名稱是fName畔勤。這個時候就可以用@JsonAlias使這個成員變量接受更多的名稱。

通用注解

  • @JsonProperty
    指定該成員變量對應的json字符串的字段名扒磁,默認情況下如果兩者相同的話不需要使用該注解庆揪。
  • @JsonIgnore
    指定該成員變量不參與序列化和反序列化

具體問題解決

下劃線和駝峰轉換

一般情況下java變量命名采用駝峰方式,而json字符串可能采用下劃線方式渗磅。解決方式為在類或者成員變量上增加以下注解

@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class)

需要注意的是雖然反序列化的時候first_name會對應到firstName變量,但是序列化的時候也會輸出為first_name

多態(tài)處理

有時候我們希望根據(jù)json字符串中某個字段的取值反序列化成不同的子類检访,比如說type為1是Student始鱼,type為2是Teacher,注意Student和Teacher必須繼承同一個父類Person脆贵。

@JsonTypeInfo(use = JsonTypeInfo.ID.NAME, property = "type", defaultImpl = Person.class)
@JsonSubTypes({
    @JsonSubTypes.Type(value = Student.class, name = "1"),
    @JsonSubTypes.Type(value = Teacher.class, name = "2")
})
public class Person {}
  • property是決定子類型的字段名稱
  • defaultImpl是默認情況下反序列化的類型医清,這里指的是當type不為1和2時
  • name是子類型對應的字段取值

帶泛型參數(shù)的List和Map的反序列化

如果我們希望ObjectMapper.readValue返回List<Person>或者Map<String, Person>,由于List<Person>.class和Map<String, Person>.class在java中是不合法的卖氨,需要借助于TypeReference

TypeReference<List<Person>> typeReference = new TypeReference<List<Person>>(){};
List<Person> list = objectMapper.readValue(jsonStr, typeReference);

jackson如何集成Spring

Spring提供的MappingJackson2MessageConverter類封裝了ObjectMapper会烙,如果希望對ObjectMapper進行定制,可以自己生成一個MappingJackson2MessageConverter對象并注冊為bean

只對部分成員變量序列化同時不影響反序列化

有時候我們希望只對部分成員變量進行序列化筒捺,如果用@JsonIgnore柏腻,會同時影響反序列化。這個時候我們可以用@JsonView注解指定某個視圖類的序列化結果包含該成員變量系吭。

更多參考

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末五嫂,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌沃缘,老刑警劉巖躯枢,帶你破解...
    沈念sama閱讀 217,542評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異槐臀,居然都是意外死亡锄蹂,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評論 3 394
  • 文/潘曉璐 我一進店門水慨,熙熙樓的掌柜王于貴愁眉苦臉地迎上來得糜,“玉大人,你說我怎么就攤上這事讥巡∠颇叮” “怎么了?”我有些...
    開封第一講書人閱讀 163,912評論 0 354
  • 文/不壞的土叔 我叫張陵欢顷,是天一觀的道長槽棍。 經常有香客問我,道長抬驴,這世上最難降的妖魔是什么炼七? 我笑而不...
    開封第一講書人閱讀 58,449評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮布持,結果婚禮上豌拙,老公的妹妹穿的比我還像新娘。我一直安慰自己题暖,他們只是感情好按傅,可當我...
    茶點故事閱讀 67,500評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著胧卤,像睡著了一般唯绍。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上枝誊,一...
    開封第一講書人閱讀 51,370評論 1 302
  • 那天况芒,我揣著相機與錄音,去河邊找鬼叶撒。 笑死绝骚,一個胖子當著我的面吹牛,可吹牛的內容都是我干的祠够。 我是一名探鬼主播压汪,決...
    沈念sama閱讀 40,193評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼古瓤!你這毒婦竟也來了蛾魄?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,074評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎滴须,沒想到半個月后舌狗,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經...
    沈念sama閱讀 45,505評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡扔水,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,722評論 3 335
  • 正文 我和宋清朗相戀三年痛侍,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片魔市。...
    茶點故事閱讀 39,841評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡主届,死狀恐怖,靈堂內的尸體忽然破棺而出待德,到底是詐尸還是另有隱情君丁,我是刑警寧澤,帶...
    沈念sama閱讀 35,569評論 5 345
  • 正文 年R本政府宣布将宪,位于F島的核電站绘闷,受9級特大地震影響,放射性物質發(fā)生泄漏较坛。R本人自食惡果不足惜印蔗,卻給世界環(huán)境...
    茶點故事閱讀 41,168評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望丑勤。 院中可真熱鬧华嘹,春花似錦、人聲如沸法竞。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽岔霸。三九已至薛躬,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間秉剑,已是汗流浹背泛豪。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評論 1 269
  • 我被黑心中介騙來泰國打工稠诲, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留侦鹏,地道東北人。 一個月前我還...
    沈念sama閱讀 47,962評論 2 370
  • 正文 我出身青樓臀叙,卻偏偏與公主長得像略水,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子劝萤,可洞房花燭夜當晚...
    茶點故事閱讀 44,781評論 2 354

推薦閱讀更多精彩內容