Java Jackson之ObjectMapper常用用法總結(jié)
ObjectMapper的使用
基本使用
ObjectMapper 是 Jackson 序列化和反序列化 JSON 和 Java 對象的核心類,提供了許多用于定制序列化和反序列化的方法和配置選項(xiàng)。
以下是 ObjectMapper 的基本使用示例:
- 序列化示例:
// 創(chuàng)建 ObjectMapper 對象 ObjectMapper objectMapper = new ObjectMapper(); // 將 Java 對象序列化為 JSON 字符串 String jsonString = objectMapper.writeValueAsString(obj);
- 反序列化示例:
// 創(chuàng)建 ObjectMapper 對象 ObjectMapper objectMapper = new ObjectMapper(); // 將 JSON 字符串反序列化為 Java 對象 MyClass myObj = objectMapper.readValue(jsonString, MyClass.class);
其中,writeValueAsString 方法用于將 Java 對象序列化為 JSON 字符串,readValue 方法用于將 JSON 字符串反序列化為 Java 對象。這里的 MyClass 表示需要反序列化成的 Java 對象類型。
在進(jìn)行序列化和反序列化時(shí),ObjectMapper 會(huì)自動(dòng)根據(jù) Java 對象的屬性和 JSON 的鍵值對進(jìn)行映射,進(jìn)行相應(yīng)的轉(zhuǎn)換。例如,Java 對象的屬性名為 propertyName,JSON 中的鍵名為 keyName,則 ObjectMapper 會(huì)自動(dòng)將它們進(jìn)行對應(yīng),將 propertyName 的值序列化為 keyName 的值。
除了以上基本用法,ObjectMapper 還提供了很多其他的序列化和反序列化方法和配置選項(xiàng),例如定制序列化規(guī)則、處理 JSON 中的日期格式、處理空值等等。
- 定制序列化規(guī)則
可以使用 Jackson 提供的注解來定制序列化規(guī)則,如 @JsonInclude、@JsonIgnore、@JsonProperty 等。也可以通過實(shí)現(xiàn) JsonSerializer 接口來自定義序列化規(guī)則
- 處理 JSON 中的日期格式
可以使用 Jackson 提供的注解 @JsonFormat 來控制日期格式,也可以通過自定義序列化器來控制日期格式
- 處理空值
可以使用 Jackson 提供的注解 @JsonInclude 來控制序列化時(shí)是否包含空值,也可以通過配置 ObjectMapper 來控制是否包含空值
其他用法
自定義序列化和反序列化
注解:可以在類或?qū)傩陨咸砑幼⒔鈦碜远x序列化和反序列化的行為,例如@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)地修改類的序列化和反序列化行為
Mixin:通過Mixin機(jī)制,可以在運(yùn)行時(shí)動(dòng)態(tà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è)對象轉(zhuǎn)換為另一個(gè)類型的對象。
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),可以通過ObjectMapper的各種方法進(jìn)行配置。例如,可以通過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: 序列化空對象時(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 中包含注釋,默認(rèn)為 false。
- JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES: 是否允許 JSON 中的屬性名不使用雙引號包圍,默認(rèn)為 false。
除了上述常用的屬性配置外,ObjectMapper 還提供了很多其他的配置選項(xiàng),如時(shí)間格式化、空值處理、注解處理等,可以根據(jù)實(shí)際情況進(jìn)行選擇和定制化。
Jackson常用注解
Jackson 是一個(gè)用于序列化和反序列化 Java 對象與 JSON 數(shù)據(jù)的庫,它提供了很多注解來定制序列化和反序列化的過程。以下是 Jackson 常用的注解及其作用:
- @JsonInclude:控制序列化時(shí)是否包含某些屬性,用于過濾 null 值或默認(rèn)值;
- @JsonIgnore:排除某些屬性不參與序列化或反序列化;
- @JsonProperty:指定屬性在序列化后的名稱;
- @JsonFormat:控制日期、時(shí)間、數(shù)字等類型的序列化和反序列化格式;
- @JsonTypeInfo:支持多態(tài)序列化和反序列化;
- @JsonSubTypes:定義多態(tài)類型的子類;
- @JsonAlias:定義屬性的別名,用于兼容不同版本的 JSON 數(shù)據(jù)格式;
- @JsonRawValue:將屬性值作為原始 JSON 數(shù)據(jù)序列化。
這些注解可以在類、屬性或者 getter/setter 方法上使用,以達(dá)到控制序列化和反序列化的效果。
@JsonProperty
這個(gè)注解用于將一個(gè)屬性或方法序列化或反序列化為指定的名稱。
例如,定義一個(gè) Person 類:
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 類:
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 類:
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 類:
@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 用來指定類型信息的序列化和反序列化方式,使用 JsonTypeInfo.Id.NAME 表示使用名稱作為類型標(biāo)識,并通過 property 屬性指定類型標(biāo)識的屬性名。@JsonSubTypes 用來指定具體的子類型,使用 @JsonSubTypes.Type 注解指定子類型的類和類型標(biāo)識。
@JsonAlias
@JsonAlias 注解可以指定多個(gè)屬性名稱作為別名
反序列化時(shí)被用來匹配。如果匹配到任意一個(gè)別名,則該別名對應(yīng)的屬性值就會(huì)被賦值給當(dāng)前屬性
需要注意的是,如果同時(shí)存在多個(gè)別名匹配到了同一個(gè)屬性,序列化以最后一個(gè)匹配到的別名對應(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 注解來指定多個(gè)屬性名的映射關(guān)系,用于序列化和反序列化。在序列化時(shí),會(huì)使用注解中的任意一個(gè)屬性名作為映射關(guān)系;在反序列化時(shí),也會(huì)根據(jù)注解中的屬性名進(jìn)行映射
@JsonRawValue
@JsonRawValue注解表示一個(gè)屬性值應(yīng)該被直接寫入JSON而不是被序列化為雙引號中的字符串。它可以用于String屬性或?qū)傩缘膅etter方法上。使用這個(gè)注解需要注意安全問題,因?yàn)樵贾挡粫?huì)被轉(zhuǎn)義,可能會(huì)產(chǎn)生安全漏洞
假設(shè)有一個(gè)User類,其中有一個(gè)注解為@JsonRawValue的String類型屬性。
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對象時(shí),info屬性的值會(huì)直接被寫入JSON中。
總結(jié)
到此這篇關(guān)于Java Jackson之ObjectMapper常用用法總結(jié)的文章就介紹到這了,更多相關(guān)Jackson ObjectMapper用法內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Mybatis的類型轉(zhuǎn)換接口TypeHandler
這篇文章主要介紹了Mybatis的類型轉(zhuǎn)換接口TypeHandler,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的朋友可以參考一下2022-08-08
使用Java語言實(shí)現(xiàn)一個(gè)冒泡排序
冒泡排序也是一種簡單直觀的排序算法,基本思想是多次遍歷要排序的數(shù)組,每次比較相鄰的元素,如果順序不對就交換它們的位置,本篇文章將通過IDE使用 Java 語言實(shí)現(xiàn)一個(gè)冒泡排序,需要的朋友可以參考下2024-03-03
Java Scanner類用法及nextLine()產(chǎn)生的換行符問題實(shí)例分析
這篇文章主要介紹了Java Scanner類用法及nextLine()產(chǎn)生的換行符問題,結(jié)合實(shí)例形式分析了Scanner類功能、hasNextInt()和nextInt()方法使用及nextLine()產(chǎn)生的換行符問題解決方法,需要的朋友可以參考下2019-03-03
Maven中pom.xml文件報(bào)錯(cuò)的原因解決
創(chuàng)建Maven項(xiàng)目的時(shí)候,如果你選擇的Packaging為war,那么就會(huì)報(bào)錯(cuò),本文主要介紹了Maven中pom.xml文件報(bào)錯(cuò)的原因解決,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-07-07
Springboot啟動(dòng)后執(zhí)行方法小結(jié)
本文主要介紹了Springboot啟動(dòng)后執(zhí)行方法小結(jié),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-04-04
IDEA無法啟動(dòng),重裝后也無法啟動(dòng)的解決方案
在IDEA中調(diào)整idea64.exe.vmoptions文件后導(dǎo)致關(guān)閉后啟動(dòng)IDEA失敗,解決方法是調(diào)整C盤下的idea64.exe.vmoptions文件,將參數(shù)與IDEA目錄下的文件一致2025-11-11
簡單實(shí)現(xiàn)java抽獎(jiǎng)系統(tǒng)
這篇文章主要教大家如何簡單實(shí)現(xiàn)java抽獎(jiǎng)系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-01-01
MyBatis使用CASE WHEN進(jìn)行批量更新的高效寫法
當(dāng)我們使用mybatis的時(shí)候,可能經(jīng)常會(huì)碰到一批數(shù)據(jù)的批量更新問題,因?yàn)槿绻粭l數(shù)據(jù)一更新,那每一條數(shù)據(jù)就需要涉及到一次數(shù)據(jù)庫的操作,包括網(wǎng)絡(luò)IO以及磁盤IO,可想而知,這個(gè)效率是非常低下的,那么今天我們就來總結(jié)一下,如何使用mybatis做批量更新,需要的朋友可以參考下2025-10-10

