Java Jackson之ObjectMapper常用用法總結(jié)
ObjectMapper的使用
基本使用
ObjectMapper 是 Jackson 序列化和反序列化 JSON 和 Java 對(duì)象的核心類(lèi),提供了許多用于定制序列化和反序列化的方法和配置選項(xiàng)。
以下是 ObjectMapper 的基本使用示例:
- 序列化示例:
// 創(chuàng)建 ObjectMapper 對(duì)象 ObjectMapper objectMapper = new ObjectMapper(); // 將 Java 對(duì)象序列化為 JSON 字符串 String jsonString = objectMapper.writeValueAsString(obj);
- 反序列化示例:
// 創(chuàng)建 ObjectMapper 對(duì)象 ObjectMapper objectMapper = new ObjectMapper(); // 將 JSON 字符串反序列化為 Java 對(duì)象 MyClass myObj = objectMapper.readValue(jsonString, MyClass.class);
其中,writeValueAsString
方法用于將 Java 對(duì)象序列化為 JSON 字符串,readValue
方法用于將 JSON 字符串反序列化為 Java 對(duì)象。這里的 MyClass
表示需要反序列化成的 Java 對(duì)象類(lèi)型。
在進(jìn)行序列化和反序列化時(shí),ObjectMapper 會(huì)自動(dòng)根據(jù) Java 對(duì)象的屬性和 JSON 的鍵值對(duì)進(jìn)行映射,進(jìn)行相應(yīng)的轉(zhuǎn)換。例如,Java 對(duì)象的屬性名為 propertyName
,JSON 中的鍵名為 keyName
,則 ObjectMapper 會(huì)自動(dòng)將它們進(jìn)行對(duì)應(yīng),將 propertyName
的值序列化為 keyName
的值。
除了以上基本用法,ObjectMapper 還提供了很多其他的序列化和反序列化方法和配置選項(xiàng),例如定制序列化規(guī)則、處理 JSON 中的日期格式、處理空值等等。
- 定制序列化規(guī)則
可以使用 Jackson 提供的注解來(lái)定制序列化規(guī)則,如 @JsonInclude、@JsonIgnore、@JsonProperty 等。也可以通過(guò)實(shí)現(xiàn) JsonSerializer 接口來(lái)自定義序列化規(guī)則
- 處理 JSON 中的日期格式
可以使用 Jackson 提供的注解 @JsonFormat 來(lái)控制日期格式,也可以通過(guò)自定義序列化器來(lái)控制日期格式
- 處理空值
可以使用 Jackson 提供的注解 @JsonInclude 來(lái)控制序列化時(shí)是否包含空值,也可以通過(guò)配置 ObjectMapper 來(lái)控制是否包含空值
其他用法
自定義序列化和反序列化
注解:可以在類(lèi)或?qū)傩陨咸砑幼⒔鈦?lái)自定義序列化和反序列化的行為,例如@JsonSerialize和@JsonDeserialize。
public class Person { @JsonSerialize(using = CustomDateSerializer.class) private Date birthday; @JsonDeserialize(using = CustomDateDeserializer.class) private Date registerTime; // getters and setters } public class CustomDateSerializer extends JsonSerializer<Date> { @Override public void serialize(Date value, JsonGenerator gen, SerializerProvider serializers) throws IOException { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); gen.writeString(sdf.format(value)); } } public class CustomDateDeserializer extends JsonDeserializer<Date> { @Override public Date deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); String dateStr = p.getText(); try { return sdf.parse(dateStr); } catch (ParseException e) { throw new IOException("Failed to parse date: " + dateStr, e); } } }
運(yùn)行時(shí)動(dòng)態(tài)地修改類(lèi)的序列化和反序列化行為
Mixin:通過(guò)Mixin機(jī)制,可以在運(yùn)行時(shí)動(dòng)態(tài)地修改類(lèi)的序列化和反序列化行為。
public class Person { private String name; private int age; // getters and setters } public interface PersonMixin { @JsonProperty("full_name") String getName(); @JsonIgnore int getAge(); } ObjectMapper objectMapper = new ObjectMapper(); objectMapper.addMixIn(Person.class, PersonMixin.class);
多態(tài)序列化和反序列化
多態(tài):使用@JsonTypeInfo和@JsonSubTypes注解,可以支持多態(tài)序列化和反序列化。
@JsonTypeInfo( use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type" ) @JsonSubTypes({ @JsonSubTypes.Type(value = Rectangle.class, name = "rectangle"), @JsonSubTypes.Type(value = Circle.class, name = "circle") }) public abstract class Shape { // ... } public class Rectangle extends Shape { // ... } public class Circle extends Shape { // ... } ObjectMapper objectMapper = new ObjectMapper(); Shape rectangle = new Rectangle(); Shape circle = new Circle(); String rectangleJson = objectMapper.writeValueAsString(rectangle); String circleJson = objectMapper.writeValueAsString(circle);
轉(zhuǎn)換
轉(zhuǎn)換:使用ObjectMapper的convertValue方法,可以將一個(gè)對(duì)象轉(zhuǎn)換為另一個(gè)類(lèi)型的對(duì)象。
public class Person { private String name; private int age; // getters and setters } public class PersonDto { private String name; private int age; // getters and setters } ObjectMapper objectMapper = new ObjectMapper(); Person person = new Person("John", 20); PersonDto personDto = objectMapper.convertValue(person, PersonDto.class);
序列化和反序列化選項(xiàng)
ObjectMapper提供了許多序列化和反序列化選項(xiàng),可以通過(guò)ObjectMapper的各種方法進(jìn)行配置。例如,可以通過(guò)configure方法設(shè)置SerializationFeature和DeserializationFeature等選項(xiàng)
ObjectMapper objectMapper = new ObjectMapper(); objectMapper.configure(SerializationFeature.INDENT_OUTPUT, true); String json = objectMapper.writeValueAsString(person);
以下是一些常用的屬性配置及其作用:
- SerializationFeature.WRITE_DATES_AS_TIMESTAMPS: 序列化日期時(shí)是否使用時(shí)間戳,默認(rèn)為 true,即使用時(shí)間戳,設(shè)為 false 可以將日期格式化成字符串。
- SerializationFeature.FAIL_ON_EMPTY_BEANS: 序列化空對(duì)象時(shí)是否拋出異常,默認(rèn)為 true。
- SerializationFeature.INDENT_OUTPUT: 是否縮進(jìn)輸出,默認(rèn)為 false。
- SerializationFeature.WRITE_NULL_MAP_VALUES: 是否序列化 null 值屬性,默認(rèn)為 true。
- DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES: 反序列化時(shí)是否拋出異常,當(dāng)遇到未知屬性時(shí),默認(rèn)為 true。
- DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_AS_NULL: 是否將未知的枚舉值反序列化成 null,默認(rèn)為 false。
- DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT: 是否將空字符串反序列化成 null,默認(rèn)為 false。
- JsonParser.Feature.ALLOW_COMMENTS: 是否允許 JSON 中包含注釋?zhuān)J(rèn)為 false。
- JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES: 是否允許 JSON 中的屬性名不使用雙引號(hào)包圍,默認(rèn)為 false。
除了上述常用的屬性配置外,ObjectMapper 還提供了很多其他的配置選項(xiàng),如時(shí)間格式化、空值處理、注解處理等,可以根據(jù)實(shí)際情況進(jìn)行選擇和定制化。
Jackson常用注解
Jackson 是一個(gè)用于序列化和反序列化 Java 對(duì)象與 JSON 數(shù)據(jù)的庫(kù),它提供了很多注解來(lái)定制序列化和反序列化的過(guò)程。以下是 Jackson 常用的注解及其作用:
- @JsonInclude:控制序列化時(shí)是否包含某些屬性,用于過(guò)濾 null 值或默認(rèn)值;
- @JsonIgnore:排除某些屬性不參與序列化或反序列化;
- @JsonProperty:指定屬性在序列化后的名稱(chēng);
- @JsonFormat:控制日期、時(shí)間、數(shù)字等類(lèi)型的序列化和反序列化格式;
- @JsonTypeInfo:支持多態(tài)序列化和反序列化;
- @JsonSubTypes:定義多態(tài)類(lèi)型的子類(lèi);
- @JsonAlias:定義屬性的別名,用于兼容不同版本的 JSON 數(shù)據(jù)格式;
- @JsonRawValue:將屬性值作為原始 JSON 數(shù)據(jù)序列化。
這些注解可以在類(lèi)、屬性或者 getter/setter 方法上使用,以達(dá)到控制序列化和反序列化的效果。
@JsonProperty
這個(gè)注解用于將一個(gè)屬性或方法序列化或反序列化為指定的名稱(chēng)。
例如,定義一個(gè) Person 類(lèi):
public class Person { @JsonProperty("name") private String fullName; private int age; public Person(String fullName, int age) { this.fullName = fullName; this.age = age; } // getters and setters }
在這個(gè)示例中,我們使用 @JsonProperty 注解將 fullName 屬性序列化為 “name”,而不是默認(rèn)的 “fullName”。
@JsonIgnore
這個(gè)注解用于忽略某個(gè)屬性或方法,不進(jìn)行序列化或反序列化。
例如,定義一個(gè) Student 類(lèi):
public class Student { private String name; private int age; @JsonIgnore private String password; public Student(String name, int age, String password) { this.name = name; this.age = age; this.password = password; } // getters and setters }
在這個(gè)示例中,我們使用 @JsonIgnore 注解忽略 password 屬性,不進(jìn)行序列化或反序列化。
@JsonFormat
這個(gè)注解用于指定日期、時(shí)間等屬性的序列化和反序列化格式。
例如,定義一個(gè) Order 類(lèi):
public class Order { private String id; private Date createTime; public Order(String id, Date createTime) { this.id = id; this.createTime = createTime; } // getters and setters }
在這個(gè)示例中,我們使用 @JsonFormat 注解指定 createTime 屬性的序列化格式:
public class Order { private String id; @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss", timezone="GMT+8") private Date createTime; public Order(String id, Date createTime) { this.id = id; this.createTime = createTime; } // getters and setters }
在這個(gè)示例中,我們指定 createTime 屬性的序列化格式為 “yyyy-MM-dd HH:mm:ss”,時(shí)區(qū)為 “GMT+8”
- @JsonInclude
這個(gè)注解用于指定序列化時(shí)包含哪些屬性,排除哪些屬性。
例如,定義一個(gè) Book 類(lèi):
@JsonInclude(JsonInclude.Include.NON_NULL) public class Book { private String title; private String author; private String isbn; private Integer pages; public Book(String title, String author, String isbn, Integer pages) { this.title = title; this.author = author; this.isbn = isbn; this.pages = pages; } // getters and setters }
在這個(gè)示例中,我們使用 @JsonInclude 注解指定序列化時(shí)只包含非空屬性,排除為 null 的屬性。這個(gè)示例中,序列化時(shí)只包含 title、author、isbn 這三個(gè)屬性。
@JsonTypeInfo 和 @JsonSubTypes
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "animalType") @JsonSubTypes({ @JsonSubTypes.Type(value = Dog.class, name = "dog"), @JsonSubTypes.Type(value = Cat.class, name = "cat") }) public abstract class Animal { private String name; // getter and setter } public class Dog extends Animal { private String breed; // getter and setter } public class Cat extends Animal { private boolean hasClaws; // getter and setter } // 序列化 Animal dog = new Dog(); ObjectMapper mapper = new ObjectMapper(); String json = mapper.writeValueAsString(dog); // 輸出結(jié)果 { "name":null, "animalType":"dog", "breed":null } // 反序列化 String json = "{\"name\":\"Lucy\",\"animalType\":\"dog\",\"breed\":\"Golden Retriever\"}"; Animal animal = mapper.readValue(json, Animal.class); // 輸出結(jié)果 Dog{name='Lucy', breed='Golden Retriever'}
在上面的例子中,使用了 @JsonTypeInfo 和 @JsonSubTypes 注解實(shí)現(xiàn)了多態(tài)序列化和反序列化。@JsonTypeInfo 用來(lái)指定類(lèi)型信息的序列化和反序列化方式,使用 JsonTypeInfo.Id.NAME 表示使用名稱(chēng)作為類(lèi)型標(biāo)識(shí),并通過(guò) property 屬性指定類(lèi)型標(biāo)識(shí)的屬性名。@JsonSubTypes 用來(lái)指定具體的子類(lèi)型,使用 @JsonSubTypes.Type 注解指定子類(lèi)型的類(lèi)和類(lèi)型標(biāo)識(shí)。
@JsonAlias
@JsonAlias 注解可以指定多個(gè)屬性名稱(chēng)作為別名
反序列化時(shí)被用來(lái)匹配。如果匹配到任意一個(gè)別名,則該別名對(duì)應(yīng)的屬性值就會(huì)被賦值給當(dāng)前屬性
需要注意的是,如果同時(shí)存在多個(gè)別名匹配到了同一個(gè)屬性,序列化以最后一個(gè)匹配到的別名對(duì)應(yīng)的值為準(zhǔn)
public class Person { @JsonAlias({"name", "personName"}) private String name; private int age; // getter and setter } // 序列化 Person person = new Person(); person.setName("Tom"); person.setAge(20); ObjectMapper mapper = new ObjectMapper(); String json = mapper.writeValueAsString(person); // 輸出結(jié)果 {"personName":"Tom","age":20} // 反序列化 String json = "{\"name\":\"Lucy\",\"age\":18}"; Person person = mapper.readValue(json, Person.class); // 輸出結(jié)果 Person{name='Lucy', age=18}
在上面的例子中,使用了 @JsonAlias 注解來(lái)指定多個(gè)屬性名的映射關(guān)系,用于序列化和反序列化。在序列化時(shí),會(huì)使用注解中的任意一個(gè)屬性名作為映射關(guān)系;在反序列化時(shí),也會(huì)根據(jù)注解中的屬性名進(jìn)行映射
@JsonRawValue
@JsonRawValue注解表示一個(gè)屬性值應(yīng)該被直接寫(xiě)入JSON而不是被序列化為雙引號(hào)中的字符串。它可以用于String屬性或?qū)傩缘膅etter方法上。使用這個(gè)注解需要注意安全問(wèn)題,因?yàn)樵贾挡粫?huì)被轉(zhuǎn)義,可能會(huì)產(chǎn)生安全漏洞
假設(shè)有一個(gè)User類(lèi),其中有一個(gè)注解為@JsonRawValue的String類(lèi)型屬性。
public class User { private String name; @JsonRawValue private String info; public User(String name, String info) { this.name = name; this.info = info; } public String getName() { return name; } public String getInfo() { return info; } }
當(dāng)我們序列化User對(duì)象時(shí),info屬性的值會(huì)直接被寫(xiě)入JSON中。
總結(jié)
到此這篇關(guān)于Java Jackson之ObjectMapper常用用法總結(jié)的文章就介紹到這了,更多相關(guān)Jackson ObjectMapper用法內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java的String類(lèi)中的startsWith方法和endsWith方法示例詳解
大家應(yīng)該都知道startsWith()方法用于檢測(cè)字符串是否以指定的前綴開(kāi)始,endsWith()方法用于測(cè)試字符串是否以指定的后綴結(jié)束,本文就Java的String類(lèi)中的startsWith方法和endsWith方法給大家詳細(xì)講解,感興趣的朋友一起看看吧2023-11-11Kotlin中l(wèi)et、run、with、apply及also的用法和差別
作用域函數(shù)是Kotlin比較重要的一個(gè)特性,分為5種let、run、with、apply及also,這五個(gè)函數(shù)的工作方式非常相似,但是我們需要了解這5種函數(shù)的差異,以便在不同的場(chǎng)景更好的利用它,這篇文章主要介紹了Kotlin中l(wèi)et、run、with、apply及also的差別,需要的朋友可以參考下2023-11-11深入學(xué)習(xí)SpringCloud之SpringCloud簡(jiǎn)介
Spring Cloud是一個(gè)一站式的開(kāi)發(fā)分布式系統(tǒng)的框架,為開(kāi)發(fā)者提供了一系列的構(gòu)建分布式系統(tǒng)的工具集,本文給大家介紹springcloud的相關(guān)知識(shí),感興趣的朋友跟隨一起看看吧2021-04-04SpringAOP切入點(diǎn)規(guī)范及獲取方法參數(shù)的實(shí)現(xiàn)
這篇文章主要介紹了SpringAOP切入點(diǎn)規(guī)范及獲取方法參數(shù),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-06-06去掉IntelliJ IDEA 中 mybatis 對(duì)應(yīng)的 xml 文件警告的教程圖解
本文通過(guò)圖文并茂的形式給大家介紹了去掉IntelliJ IDEA 中 mybatis 對(duì)應(yīng)的 xml 文件警告的教程,需要的朋友可以參考下2018-06-06通過(guò)netty把百度地圖API獲取的地理位置從Android端發(fā)送到Java服務(wù)器端的操作方法
這篇文章主要介紹了通過(guò)netty把百度地圖API獲取的地理位置從Android端發(fā)送到Java服務(wù)器端,本文通過(guò)示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-10-10java與C 代碼運(yùn)行效率的對(duì)比(整理)
最近和朋友無(wú)意間討論起了 有關(guān)java 和C 的 效率問(wèn)題, (我是java 推介者, 他是 c 語(yǔ)言推介者, 他做的是嵌入式)故,想通過(guò)網(wǎng)絡(luò)查詢(xún)一下, 總結(jié)一下,兩者到底效率如何,其有何差異,原因又是啥?各種優(yōu)勢(shì)有在何處?2021-04-04關(guān)于Java的二叉樹(shù)、紅黑樹(shù)、B+樹(shù)詳解
這篇文章主要介紹了關(guān)于Java的二叉樹(shù)、紅黑樹(shù)、B+樹(shù)詳解,能同時(shí)具備數(shù)組查找快的優(yōu)點(diǎn)以及鏈表插入和刪除快的優(yōu)點(diǎn)的數(shù)據(jù)結(jié)構(gòu)就是樹(shù),需要的朋友可以參考下2023-05-05java實(shí)現(xiàn)即賦值也判斷的寫(xiě)法示例
這篇文章主要為大家介紹了java實(shí)現(xiàn)即賦值也判斷的寫(xiě)法示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-12-12