Jackson序列化(3)— Jackson中ObjectMapper配置詳解

Jackson序列化(1)— [SpringBoot2.x]-Jackson在HttpMessageConverter(消息轉(zhuǎn)換器)中的使用
Jackson序列化(2)— [SpringBoot2.x]-Spring容器中ObjectMapper
Jackson序列化(3)— Jackson中ObjectMapper配置詳解
Jackson序列化(4)— Jackson“默認(rèn)的”時(shí)間格式化類—StdDateFormat解析
Jackson序列化(5) — Jackson的ObjectMapper.DefaultTyping.NON_FINAL屬性
Jackson序列化(6)— Java使用Jackson進(jìn)行序列化

上文講述了如何在SpringBoot2.x環(huán)境下去修改容器中的ObjectMapper。那么ObjectMapper提供了什么樣的配置供開發(fā)人員操作瞒爬?

image.png

1. ObjectMapper的參數(shù)配置

1.1 針對(duì)于ObjectMapper直接配置

源碼:com.fasterxml.jackson.databind.SerializationFeature該類是一個(gè)枚舉類型冒黑,只有一個(gè)boolean類型的參數(shù)派殷。即開啟/禁用該設(shè)置德澈。一般我們使用ObjectMapper objectMapper = new ObjectMapper();創(chuàng)建出來的ObjectMapper對(duì)象洒宝,實(shí)際上包含了SerializationFeature類的默認(rèn)配置蝇闭。我們?nèi)粝胄薷呐渲煤辟耍梢允褂孟旅娴姆椒ǎ绱a1所示:

代碼1:修改ObjectMapper中的SerializationFeature參數(shù)陌知。

//SerializationFeature代表配置他托;state代表狀態(tài)
public ObjectMapper configure(SerializationFeature f, boolean state)
//啟用SerializationFeature配置
public ObjectMapper enable(SerializationFeature f)
//禁用配置
public ObjectMapper disable(SerializationFeature f)

1.2 SpringBoot2.x使用Builder進(jìn)行配置

我們按照SpringBoot2.x的思路,需要自定義Jackson2ObjectMapperBuilderCustomizer子類并加入到IOC容器中仆葡。

并且在SpringBoot2.x中赏参,引入了下面的依賴。使用builder創(chuàng)建ObjectMapper時(shí)注冊(cè)objectMapper.registerModule(new JavaTimeModule())解決了JDK1.8的新時(shí)間類LocalDateTime的問題登刺。

<dependency>
  <groupId>com.fasterxml.jackson.datatype</groupId>
  <artifactId>jackson-datatype-jsr310</artifactId>
</dependency>

核心代碼:可以調(diào)整ObjectMapper序列化和反序列化特性籽腕。

@Component
public class MyJackson2ObjectMapperBuilderCustomizer implements Jackson2ObjectMapperBuilderCustomizer, Ordered {
    @Override
    public void customize(Jackson2ObjectMapperBuilder jacksonObjectMapperBuilder) {
        //若POJO對(duì)象的屬性值為null,序列化時(shí)不進(jìn)行顯示
        jacksonObjectMapperBuilder.serializationInclusion(JsonInclude.Include.NON_NULL);
        //若POJO對(duì)象的屬性值為""纸俭,序列化時(shí)不進(jìn)行顯示
        jacksonObjectMapperBuilder.serializationInclusion(JsonInclude.Include.NON_EMPTY);
        //DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES相當(dāng)于配置皇耗,JSON串含有未知字段時(shí),反序列化依舊可以成功
        jacksonObjectMapperBuilder.failOnUnknownProperties(false);
        //序列化時(shí)的命名策略——駝峰命名法
        jacksonObjectMapperBuilder.propertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
        //針對(duì)于Date類型揍很,文本格式化
        jacksonObjectMapperBuilder.simpleDateFormat("yyyy-MM-dd HH:mm:ss");

        //針對(duì)于JDK新時(shí)間類郎楼。序列化時(shí)帶有T的問題,自定義格式化字符串
        JavaTimeModule javaTimeModule = new JavaTimeModule();
        javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        jacksonObjectMapperBuilder.modules(javaTimeModule);

//            jacksonObjectMapperBuilder.featuresToEnable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
        //默認(rèn)關(guān)閉窒悔,將char[]數(shù)組序列化為String類型呜袁。若開啟后序列化為JSON數(shù)組。
        jacksonObjectMapperBuilder.featuresToEnable(SerializationFeature.WRITE_CHAR_ARRAYS_AS_JSON_ARRAYS);

        //默認(rèn)開啟简珠,若map的value為null闸天,則不對(duì)map條目進(jìn)行序列化秽褒。(已廢棄)奏黑。
        // 推薦使用:jacksonObjectMapperBuilder.serializationInclusion(JsonInclude.Include.NON_NULL);
        jacksonObjectMapperBuilder.featuresToDisable(SerializationFeature.WRITE_NULL_MAP_VALUES);

        //默認(rèn)開啟腊凶,將Date類型序列化為數(shù)字時(shí)間戳(毫秒表示)。關(guān)閉后祭玉,序列化為文本表現(xiàn)形式(2019-10-23T01:58:58.308+0000)
        //若設(shè)置時(shí)間格式化氧映。那么均輸出格式化的時(shí)間類型。
        jacksonObjectMapperBuilder.featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
        //默認(rèn)關(guān)閉脱货,在類上使用@JsonRootName(value="rootNode")注解時(shí)是否可以包裹Root元素岛都。
        // (https://blog.csdn.net/blueheart20/article/details/52212221)
//            jacksonObjectMapperBuilder.featuresToEnable(SerializationFeature.WRAP_ROOT_VALUE);
        //默認(rèn)開啟:如果一個(gè)類沒有public的方法或?qū)傩詴r(shí),會(huì)導(dǎo)致序列化失敗振峻。關(guān)閉后臼疫,會(huì)得到一個(gè)空J(rèn)SON串。
        jacksonObjectMapperBuilder.featuresToDisable(SerializationFeature.FAIL_ON_EMPTY_BEANS);

        //默認(rèn)關(guān)閉扣孟,即以文本(ISO-8601)作為Key多矮,開啟后,以時(shí)間戳作為Key
        jacksonObjectMapperBuilder.featuresToEnable(SerializationFeature.WRITE_DATE_KEYS_AS_TIMESTAMPS);

        //默認(rèn)禁用哈打,禁用情況下,需考慮WRITE_ENUMS_USING_TO_STRING配置讯壶。啟用后料仗,ENUM序列化為數(shù)字
        jacksonObjectMapperBuilder.featuresToEnable(SerializationFeature.WRITE_ENUMS_USING_INDEX);

        //僅當(dāng)WRITE_ENUMS_USING_INDEX為禁用時(shí)(默認(rèn)禁用),該配置生效
        //默認(rèn)關(guān)閉伏蚊,枚舉類型序列化方式立轧,默認(rèn)情況下使用Enum.name()。開啟后,使用Enum.toString()氛改。注:需重寫Enum的toString方法;
        jacksonObjectMapperBuilder.featuresToEnable(SerializationFeature.WRITE_ENUMS_USING_TO_STRING);

        //默認(rèn)開啟帐萎,空Collection集合類型輸出空J(rèn)SON串。關(guān)閉后取消顯示胜卤。(已過時(shí))
        // 推薦使用serializationInclusion(JsonInclude.Include.NON_EMPTY);
        jacksonObjectMapperBuilder.featuresToEnable(SerializationFeature.WRITE_EMPTY_JSON_ARRAYS);

        //默認(rèn)關(guān)閉疆导,當(dāng)集合Collection或數(shù)組一個(gè)元素時(shí)返回:"list":["a"]。開啟后葛躏,"list":"a"
        //需要注意澈段,和DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY 配套使用,要么都開啟舰攒,要么都關(guān)閉败富。
//            jacksonObjectMapperBuilder.featuresToEnable(SerializationFeature.WRITE_SINGLE_ELEM_ARRAYS_UNWRAPPED);

        //默認(rèn)關(guān)閉。打開后BigDecimal序列化為文本摩窃。(已棄用)兽叮,推薦使用JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN配置
//            jacksonObjectMapperBuilder.featuresToEnable(SerializationFeature.WRITE_BIGDECIMAL_AS_PLAIN);
        //默認(rèn)關(guān)閉,即使用BigDecimal.toString()序列化猾愿。開啟后鹦聪,使用BigDecimal.toPlainString序列化,不輸出科學(xué)計(jì)數(shù)法的值匪蟀。
        jacksonObjectMapperBuilder.featuresToEnable(JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN);

        /**
         * JsonGenerator.Feature的相關(guān)參數(shù)(JSON生成器)
         */

        //默認(rèn)關(guān)閉椎麦,即序列化Number類型及子類為{"amount1":1.1}。開啟后材彪,序列化為String類型观挎,即{"amount1":"1.1"}
        jacksonObjectMapperBuilder.featuresToEnable(JsonGenerator.Feature.WRITE_NUMBERS_AS_STRINGS);

        /******
         *  反序列化
         */
        //默認(rèn)關(guān)閉,當(dāng)JSON字段為""(EMPTY_STRING)時(shí)段化,解析為普通的POJO對(duì)象拋出異常嘁捷。開啟后,該P(yáng)OJO的屬性值為null显熏。
        jacksonObjectMapperBuilder.featuresToEnable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT);
        //默認(rèn)關(guān)閉
//            jacksonObjectMapperBuilder.featuresToEnable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT);
        //默認(rèn)關(guān)閉雄嚣,若POJO中不含有JSON中的屬性,則拋出異常喘蟆。開啟后缓升,不解析該字段,而不會(huì)拋出異常蕴轨。
        jacksonObjectMapperBuilder.featuresToEnable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
    }

    @Override
    public int getOrder() {
        return 1;
    }
}

官方文檔參考

【2.7.0 SerializationFeature API文檔】

【2.7.0 DeserializationFeature API文檔】

【2.7.0 JsonGenerator.Feature API文檔】

推薦閱讀

為什么設(shè)置new BigDecimal(1.10)港谊,卻得到一大串?dāng)?shù)字

BigDecimal的toString和toPlainString的區(qū)別

DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT參數(shù)為啥不起作用!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末橙弱,一起剝皮案震驚了整個(gè)濱河市歧寺,隨后出現(xiàn)的幾起案子燥狰,更是在濱河造成了極大的恐慌,老刑警劉巖斜筐,帶你破解...
    沈念sama閱讀 219,490評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件龙致,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡顷链,警方通過查閱死者的電腦和手機(jī)目代,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,581評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蕴潦,“玉大人像啼,你說我怎么就攤上這事√栋” “怎么了忽冻?”我有些...
    開封第一講書人閱讀 165,830評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)此疹。 經(jīng)常有香客問我僧诚,道長(zhǎng),這世上最難降的妖魔是什么蝗碎? 我笑而不...
    開封第一講書人閱讀 58,957評(píng)論 1 295
  • 正文 為了忘掉前任湖笨,我火速辦了婚禮,結(jié)果婚禮上蹦骑,老公的妹妹穿的比我還像新娘慈省。我一直安慰自己,他們只是感情好眠菇,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,974評(píng)論 6 393
  • 文/花漫 我一把揭開白布边败。 她就那樣靜靜地躺著,像睡著了一般捎废。 火紅的嫁衣襯著肌膚如雪笑窜。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,754評(píng)論 1 307
  • 那天登疗,我揣著相機(jī)與錄音排截,去河邊找鬼。 笑死辐益,一個(gè)胖子當(dāng)著我的面吹牛断傲,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播智政,決...
    沈念sama閱讀 40,464評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼艳悔,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了女仰?” 一聲冷哼從身側(cè)響起猜年,我...
    開封第一講書人閱讀 39,357評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎疾忍,沒想到半個(gè)月后乔外,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,847評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡一罩,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,995評(píng)論 3 338
  • 正文 我和宋清朗相戀三年杨幼,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片聂渊。...
    茶點(diǎn)故事閱讀 40,137評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡差购,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出汉嗽,到底是詐尸還是另有隱情欲逃,我是刑警寧澤,帶...
    沈念sama閱讀 35,819評(píng)論 5 346
  • 正文 年R本政府宣布饼暑,位于F島的核電站稳析,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏弓叛。R本人自食惡果不足惜彰居,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,482評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望撰筷。 院中可真熱鬧陈惰,春花似錦、人聲如沸毕籽。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,023評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽影钉。三九已至画髓,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間平委,已是汗流浹背奈虾。 一陣腳步聲響...
    開封第一講書人閱讀 33,149評(píng)論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留廉赔,地道東北人肉微。 一個(gè)月前我還...
    沈念sama閱讀 48,409評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像蜡塌,于是被迫代替她去往敵國和親碉纳。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,086評(píng)論 2 355