ObjectMapper最好用的对象转json的方式-CSDN博客 (2024)

Table of Contents
一、前言 二、ObjectMapper

一、前言

Jackson和Fastjson都是比较出名的JSON解析库,SpringMVC默认使用的是Jackson,而且在企业项目中也大多使用的是Jackson,感觉还是很有必要熟悉Jackson的基本使用的。

1. 引入Jackson

如果只是简单的Java代码,不使用Spring Boot的话,直接引入Jackson。

<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.13.1</version></dependency>

如果是使用了SpringBoot的项目,引入spring-boot-starter-web就会自动引入Jackson。

<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId></dependency>

二、ObjectMapper


我们使用Jackson等工具时,最常见的场景就是JSON的序列化和反序列化。而Jackson最常用的的就是ObjectMapper, 它提供了丰富的方法。

1. 创建ObjectMapper
如果是普通Java项目,则new一个ObjectMapper。

private ObjectMapper mapper = new ObjectMapper();


2.如果是使用Spring项目,则自动注入ObjectMapper。

@Autowiredprivate ObjectMapper objectMapper;

2. 序列化
假设有一个Java类:Student。

2.1 Java对象 转 JSON
Student student = getStudent();
String studentStr = mapper.writeValueAsString(student);
1
2
2.2 Java List 转 JSON
List<Student> studentList= getStudentList();
String studentListStr = mapper.writeValueAsString(studentList);
1
2
2.3 Java Map 转 JSON
Map<String, Object> studentMap = new HashMap<>();
studentMap.put("id", "1");
studentMap.put("name", "亚瑟");
studentMap.put("age", 33);

String studentJsonStr = mapper.writeValueAsString(studentMap);
1
2
3
4
5
6
2.4 美化输出格式
在调writeValueAsString之前先调writerWithDefaultPrettyPrinter

String studentStr = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(student);
1
2.5 序列化结果写文件
mapper.writeValue(new File(OBJECT_FILE_PATH_FOR_WRITE_FROM_SRC), student);
1
3. 反序列化
3.1 JSON 转 Java对象
String studentStr = getStudentString();
Student student = mapper.readValue(studentStr, Student.class);
1
2
3.2 JSON 转 Java List
List<Student> studentList1 = mapper.readValue(studentListStr , new TypeReference<>() {});
或者
List<Student> studentList2 = Arrays.asList(mapper.readValue(studentListStr, Student[].class));
1
2
3
3.3 JSON 转 Java Map
HashMap studentMap = mapper.readValue(studentStr, HashMap.class);
1
3.4 JSON File 转 Java对象
File file = new File(OBJECT_FILE_PATH_FROM_SRC);
Student student = mapper.readValue(file, Student.class);
1
2
3.5 JSON Reader 转 Java对象
File file = new File(OBJECT_FILE_PATH_FROM_SRC);
Reader reader = new java.io.FileReader(file);
Student student = mapper.readValue(reader, Student.class);
1
2
3
3.6 JSON InputStream 转 Java对象
InputStream inputStream = new FileInputStream(OBJECT_FILE_PATH_FROM_SRC);
Student student = mapper.readValue(inputStream, Student.class);
1
2
3.7 JSON Byte Array 转 Java对象
Student student = mapper.readValue(studentStr.getBytes(StandardCharsets.UTF_8), Student.class);
1
3.8 JSON via URL 转 Java对象
URL url = new URL("file:" + OBJECT_FILE_PATH_FROM_SRC);
Student student6 = mapper.readValue(url, Student.class);
1
2
三、Jackson注解
1. 序列化/反序列化都生效注解
1.1 @JsonIgnore
工作中一般会修饰Java类的属性上,无论序列化还是反序列化,Jackson都会忽略这个属性。
举个例子:@JsonIgnore修饰id属性

@Data
@AllArgsConstructor
@NoArgsConstructor
public class StudentTestForJsonIgnore {

@JsonIgnore
private String id;

private String name;

//注意得用Integer,而不能用int
private Integer age;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
序列化:

StudentTestForJsonIgnore stu = new StudentTestForJsonIgnore("1", "亚瑟", 30);
String stuStr = mapper.writeValueAsString(stu);
System.out.println(stuStr);
1
2
3
打印序列化结果: 忽略了id

{"name":"亚瑟","age":30}
1
反序列化:

String stuFullStr = "{\"id\":\"1\",\"name\":\"亚瑟\",\"age\":30}";
StudentTestForJsonIgnore stu2 = mapper.readValue(stuFullStr, StudentTestForJsonIgnore.class);
System.out.println(stu2.toString());
1
2
3
打印反序列化结果: 忽略了id

StudentTestForJsonIgnore(id=null, name=亚瑟, age=30)
1
1.2 @JsonIgnoreProperties
@JsonIgnoreProperties的作用和@JsonIgnore类似,但是@JsonIgnoreProperties修饰在Java类上,它可设置忽略多个属性,且可以设置ignoreUnknown = true,反序列化时,忽略在JSON中存在,但在Java类中不存在的字段,而不报异常。
举个例子:@JsonIgnoreProperties设置了"id", “age”,且设ignoreUnknown = true

@Data
@AllArgsConstructor
@NoArgsConstructor
@JsonIgnoreProperties(value = {"id", "age"}, ignoreUnknown = true)
public class StudentTestForJsonIgnoreProperties {

private String id;

private String name;

private Integer age;
}
1
2
3
4
5
6
7
8
9
10
11
12
序列化:

StudentTestForJsonIgnoreProperties stu = new StudentTestForJsonIgnoreProperties("1", "亚瑟", 30);
String stuStr = mapper.writeValueAsString(stu);
System.out.println(stuStr);
1
2
3
打印序列化结果: 忽略了"id", "age"这2个属性

{"name":"亚瑟"}
1
反序列化:

String stuFullStr = "{\"id\":\"1\",\"name\":\"亚瑟\",\"age\":30, \"nickName\":\"Yase\"}";
StudentTestForJsonIgnoreProperties stu2 = mapper.readValue(stuFullStr, StudentTestForJsonIgnoreProperties.class);
System.out.println(stu2.toString());
1
2
3
打印反序列化结果:

StudentTestForJsonIgnoreProperties(id=null, name=亚瑟, age=null)
1
1.3 @JsonIgnoreType
当其他类有该类作为属性时,该属性将被忽略。
举例:关于Student的类,添加了englishName属性。

@Data
@AllArgsConstructor
@NoArgsConstructor
public class StudentTestForJsonIgnoreType {

private String id;

private String name;

private EnglishName englishName;

private Integer age;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
EnglishName 类定义如下,用@JsonIgnoreType修饰

@Data
@NoArgsConstructor
@AllArgsConstructor
@JsonIgnoreType
public class EnglishName {
public String firstName;
public String lastName;
}
1
2
3
4
5
6
7
8
序列化:

StudentTestForJsonIgnoreType stu = new StudentTestForJsonIgnoreType("1", "亚瑟", new EnglishName("Ya", "SE"), 30);
String stuStr = mapper.writeValueAsString(stu);
System.out.println(stuStr);
1
2
3
打印序列化结果: 忽略了englishName属性

{"id":"1","name":"亚瑟","age":30}
1
反序列化:

String stuFullStr = "{\"id\":\"1\",\"name\":\"亚瑟\",\"age\":30, \"englishName\":{\"firstName\":\"Ya\",\"lastName\":\"SE\"}}";
StudentTestForJsonIgnoreType stu2 = mapper.readValue(stuFullStr, StudentTestForJsonIgnoreType.class);
System.out.println(stu2.toString());
1
2
3
打印反序列化结果:

StudentTestForJsonIgnoreType(id=1, name=亚瑟, englishName=null, age=30)
1
1.4 @JsonProperty
如果JSON中字段名和Java类中的属性名不一致时,可以用@JsonProperty修饰在属性上。

@Data
@AllArgsConstructor
@NoArgsConstructor
public class StudentTestForJsonProperty {

private String id;

@JsonProperty("studentName")
private String name;

private Integer age;
}
1
2
3
4
5
6
7
8
9
10
11
12
序列化:

StudentTestForJsonProperty stu = new StudentTestForJsonProperty("1", "亚瑟", 30);
String stuStr = mapper.writeValueAsString(stu);
System.out.println(stuStr);
1
2
3
打印序列化结果: studentName代替了name

{"id":"1","age":30,"studentName":"亚瑟"}
1
反序列化:

String stuFullStr = "{\"id\":\"1\",\"studentName\":\"亚瑟\",\"age\":30}";
StudentTestForJsonProperty stu2 = mapper.readValue(stuFullStr, StudentTestForJsonProperty.class);
System.out.println(stu2.toString());
1
2
3
打印反序列化结果: studentName的值赋值给了name属性

StudentTestForJsonProperty(id=1, name=亚瑟, age=30)
1
1.5 @JsonAnyGetter和@JsonAnySetter
@JsonAnyGetter
1.方法是非静态,没有参数的,方法名随意
2.方法返回值必须是Map类型
3.在一个实体类中仅仅用在一个方法上
4.序列化的时候json字段的key就是返回Map的key,value就是Map的value

@JsonAnySetter
1.用在非静态方法上,注解的方法必须有两个参数,第一个是json字段中的key,第二个是value,方法名随意
2.也可以用在Map对象属性上面,建议用在Map对象属性上面
3.反序列化的时候将对应不上的字段全部放到Map里面

1.5.1 非嵌套的otherAttributes
@Data
@AllArgsConstructor
@NoArgsConstructor
public class StudentTestForJsonGetSet {

private String id;

private String name;

private Integer age;

private Map<String, Object> otherAttributes = new HashMap<>();

@JsonAnyGetter
public Map<String, Object> getOtherAttributes() {
return this.otherAttributes;
}

@JsonAnySetter
public void setOtherAttributes(String name, Object value) {
this.otherAttributes.put(name, value);
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public static void main(String[] args) throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
Map<String, Object> otherAttributes = new HashMap<>();
otherAttributes.put("what", "1");
StudentTestForJsonGetSet stu = new StudentTestForJsonGetSet("1", "亚瑟", 30, otherAttributes);
//序列化
String stuStr = mapper.writeValueAsString(stu);
System.out.println(stuStr);
//反序列化
String stuFullStr = "{\"id\":\"1\",\"studentName\":\"亚瑟\",\"age\":30,\"what\":\"1\"}";
StudentTestForJsonGetSet stu2 = mapper.readValue(stuFullStr, StudentTestForJsonGetSet.class);
System.out.println(stu2.toString());
}
1
2
3
4
5
6
7
8
9
10
11
12
13
{"id":"1","name":"亚瑟","age":30,"what":"1"}
StudentTestForJsonGetSet(id=1, name=null, age=30, otherAttributes={what=1, studentName=亚瑟})
1
2
1.5.2 嵌套的otherAttributes
如果otherAttributes接收嵌套的JSON结构,则Map的Value是LinkedHashMap类型。

先准备数据

ObjectMapper mapper = new ObjectMapper();

Map<String, StudentTestForJsonGetSet> level2 = new HashMap<>();
StudentTestForJsonGetSet studentTestForJsonGetSet = new StudentTestForJsonGetSet();
studentTestForJsonGetSet.setId("1-1");
studentTestForJsonGetSet.setName("name-1-1");
studentTestForJsonGetSet.setAge(11);
level2.put("Key-1-1", studentTestForJsonGetSet);

Map<String, Object> level1 = new HashMap<>();
level1.put("Key-1", level2);

StudentTestForJsonGetSet stu = new StudentTestForJsonGetSet("1", "亚瑟", 30, level1);
1
2
3
4
5
6
7
8
9
10
11
12
13
序列化:

String stuStr = mapper.writeValueAsString(stu);
System.out.println(stuStr);
1
2
{"id":"1","name":"亚瑟","age":30,"Key-1":{"Key-1-1":{"id":"1-1","name":"name-1-1","age":11}}}
1
反序列化:

String stuFullStr = "{\"id\":\"1\",\"name\":\"亚瑟\",\"age\":30,\"Key-1\":{\"Key-1-1\":{\"id\":\"1-1\",\"name\":\"name-1-1\",\"age\":11}}}";
StudentTestForJsonGetSet stu2 = mapper.readValue(stuFullStr, StudentTestForJsonGetSet.class);
System.out.println(stu2.toString());
1
2
3


2. 仅序列化时生效注解
2.1 @JsonFormat
在序列化日期/时间值时指定格式。
下面@JsonFormat注解指定时间序列化后的格式。

@Data
@AllArgsConstructor
@NoArgsConstructor
public class StudentTestForJsonFormat {

private String id;

private String name;

private Integer age;

//默认情况下,Date序列化为自1970年1月1日以来的毫秒数(long类型)
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date time;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
序列化:

StudentTestForJsonFormat stu = new StudentTestForJsonFormat("1", "亚瑟", 30, new Date());
String stuStr = mapper.writeValueAsString(stu);
System.out.println(stuStr);
1
2
3
打印序列化结果:

{"id":"1","name":"亚瑟","age":30,"time":"2022-03-28 17:21:26"}
1
反序列化:

String stuFullStr = "{\"id\":\"1\",\"name\":\"亚瑟\",\"age\":30,\"time\":\"2022-03-07 18:39:12\"}";
StudentTestForJsonFormat stu2 = mapper.readValue(stuFullStr, StudentTestForJsonFormat.class);
System.out.println(stu2.toString());
1
2
3
打印反序列化结果:

StudentTestForJsonFormat(id=1, name=亚瑟, age=30, time=Mon Mar 07 18:39:12 CST 2022)
1
2.2 @JsonInclude
@JsonInclude是非常重要的且常用的注解,它可以修饰在类名上或者属性上,但是一般为了更加细粒度的控制,都修饰在属性上。

类型 说明
ALWAYS 这个是默认值,无论属性值是否为空,都参加序列化
NON_NULL 属性值不是NULL,才参加序列化
NON_ABSENT NON_NULL的增强版,Optional类型不是null,且isPresent()为true,才参加序列化。 实际开发中并不建议在实体类定义Optional类型的属性,如果你非要用,一定要赋默认值,比如Optional.empty()。
NON_EMPTY 属性值不是NULL,也不是"",如果是集合则isEmpty() = false,才参加序列化
NON_DEFAULT 属性值为缺省值时不序列化,比如int类型=0,String类型=null,这样不参加序列化。 实际开发中不要在实体类中用基础类型(如int,float),要用Integer代替int,具体原因参考阿里巴巴Java开发手册。
CUSTOM 结合注解JsonInclude.valueFilter和JsonInclude.contentFilter使用,这两个注解会指定一个Class,然后默认调用这个Class的空参构造方法,返回的对象eques属性值的话,序列化时就忽略。

ObjectMapper最好用的对象转json的方式-CSDN博客 (2024)
Top Articles
My Best Gluten Free Chinese Food Recipes | Say Goodbye to Takeout
22 Nourishing, Make-Ahead Postpartum Recipes
Cranes For Sale in United States| IronPlanet
55Th And Kedzie Elite Staffing
Collision Masters Fairbanks
Southeast Iowa Buy Sell Trade
Autobell Car Wash Hickory Reviews
P2P4U Net Soccer
Nordstrom Rack Glendale Photos
Craigslist Vermillion South Dakota
Nm Remote Access
Erin Kate Dolan Twitter
Diablo 3 Metascore
Void Touched Curio
Used Drum Kits Ebay
Maplestar Kemono
Busted Barren County Ky
Apne Tv Co Com
Busby, FM - Demu 1-3 - The Demu Trilogy - PDF Free Download
Espn Horse Racing Results
Eva Mastromatteo Erie Pa
CDL Rostermania 2023-2024 | News, Rumors & Every Confirmed Roster
Why Does Lawrence Jones Have Ptsd
Routing Number For Radiant Credit Union
Bennington County Criminal Court Calendar
Regal Amc Near Me
Raw Manga 1000
Airtable Concatenate
Celina Powell Lil Meech Video: A Controversial Encounter Shakes Social Media - Video Reddit Trend
Airline Reception Meaning
2021 MTV Video Music Awards: See the Complete List of Nominees - E! Online
Dei Ebill
Spectrum Outage in Queens, New York
Lindy Kendra Scott Obituary
Shoe Station Store Locator
Was heißt AMK? » Bedeutung und Herkunft des Ausdrucks
Metra Union Pacific West Schedule
EST to IST Converter - Time Zone Tool
Edward Walk In Clinic Plainfield Il
Missouri State Highway Patrol Will Utilize Acadis to Improve Curriculum and Testing Management
Etowah County Sheriff Dept
Greater Keene Men's Softball
Temu Y2K
301 Priest Dr, KILLEEN, TX 76541 - HAR.com
All-New Webkinz FAQ | WKN: Webkinz Newz
Sallisaw Bin Store
Craigslist St Helens
The Many Faces of the Craigslist Killer
Motorcycle For Sale In Deep East Texas By Owner
Msatlantathickdream
Is Chanel West Coast Pregnant Due Date
Joe Bartosik Ms
Latest Posts
Article information

Author: The Hon. Margery Christiansen

Last Updated:

Views: 5703

Rating: 5 / 5 (70 voted)

Reviews: 93% of readers found this page helpful

Author information

Name: The Hon. Margery Christiansen

Birthday: 2000-07-07

Address: 5050 Breitenberg Knoll, New Robert, MI 45409

Phone: +2556892639372

Job: Investor Mining Engineer

Hobby: Sketching, Cosplaying, Glassblowing, Genealogy, Crocheting, Archery, Skateboarding

Introduction: My name is The Hon. Margery Christiansen, I am a bright, adorable, precious, inexpensive, gorgeous, comfortable, happy person who loves writing and wants to share my knowledge and understanding with you.