文章目录
jackson的序列化和反序列化
SpringBoot内置了jackson
来实现JSON的序列化和反序列化。
jackson
使用ObjectMapper
类将POJO对象序列化为JSON字符串,也能将JSON字符串反序列化为POJO对象。
下面我们来看具体的例子。
将POJO对象序列化为JSON字符串
- com.jepcc.example.pojo.Student
package com.jepcc.example.pojo;
public class Student {
private String id;
private String name;
private int age;
private String gender;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
@Override
public String toString() {
final StringBuffer sb = new StringBuffer("Student{");
sb.append("id='").append(id).append('\'');
sb.append(", name='").append(name).append('\'');
sb.append(", age=").append(age);
sb.append(", gender='").append(gender).append('\'');
sb.append('}');
return sb.toString();
}
}
- com.jepcc.example.controller.StudentController
package com.jepcc.example.controller;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.jepcc.example.pojo.Student;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/test")
public class StudentController {
@Autowired
private ObjectMapper mapper;
@GetMapping("/pojo2string")
public String test() throws JsonProcessingException {
Student stu = new Student();
stu.setId("1");
stu.setName("Nicholas");
stu.setAge(18);
stu.setGender("male");
String str = mapper.writeValueAsString(stu);
return str;
}
}
- 调用接口
/test/pojo2string
,进行测试
将JSON字符串转换为POJO对象
在com.jepcc.example.controller.StudentController
中添加接口/test/string2pojo
对应内容,如下:
package com.jepcc.example.controller;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.jepcc.example.pojo.Student;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/test")
public class StudentController {
@Autowired
private ObjectMapper mapper;
@GetMapping("/pojo2string")
public String test() throws JsonProcessingException {
Student stu = new Student();
stu.setId("1");
stu.setName("Nicholas");
stu.setAge(18);
stu.setGender("male");
String str = mapper.writeValueAsString(stu);
return str;
}
@GetMapping("/string2pojo")
public Student convert() throws JsonProcessingException {
String str = "{\"id\":\"10\",\"name\":\"Lucy\",\"age\":20,\"gender\":\"female\"}";
Student stu = mapper.readValue(str,Student.class);
return stu;
}
}
对接口/test/string2pojo
进行测试。
jackson的注解
jackson包含很多注解,用于个性化序列化和反序列化操作。比如,
@JsonProperty(alias)
,作用在属性上,为属性指定别名。@JsonIgnore
,作用在属性上,用此注解来忽略属性。@JsonIgnoreProperties({propertyName1,propertyName2})
,作用在类上,表示忽略一组属性。@JsonFormat(pattern="")
,用于格式化日期。比如@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
,将时间格式化为“年-月-日 时:分:秒”。
再来看个具体的例子吧。
- com.jepcc.example.pojo.Student
package com.jepcc.example.pojo;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.Date;
public class Student {
private String id;
private String name;
private int age;
@JsonIgnore
private String gender;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonProperty("bd")
private Date birthday;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
@Override
public String toString() {
final StringBuffer sb = new StringBuffer("Student{");
sb.append("id='").append(id).append('\'');
sb.append(", name='").append(name).append('\'');
sb.append(", age=").append(age);
sb.append(", gender='").append(gender).append('\'');
sb.append(", birthday=").append(birthday);
sb.append('}');
return sb.toString();
}
}
- com.jepcc.example.controller.StudentController
package com.jepcc.example.controller;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.jepcc.example.pojo.Student;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Date;
@RestController
@RequestMapping("/test")
public class StudentController {
@Autowired
private ObjectMapper mapper;
@GetMapping("/pojo2string")
public String test() throws JsonProcessingException {
Student stu = new Student();
stu.setId("1");
stu.setName("Nicholas");
stu.setAge(18);
stu.setGender("male");
stu.setBirthday(new Date());
String str = mapper.writeValueAsString(stu);
return str;
}
@GetMapping("/string2pojo")
public Student convert() throws JsonProcessingException {
String str = "{\"id\":\"10\",\"name\":\"Lucy\",\"age\":20,\"gender\":\"female\",\"bd\":"+new Date().getTime()+"}";
Student stu = mapper.readValue(str,Student.class);
return stu;
}
}
- 对接口:
/test/pojo2string
和/test/string2pojo
分别进行测试。
GET http://localhost:8000/test/pojo2string
Content-Type: application/json
###
GET http://localhost:8000/test/string2pojo
Content-Type: application/json
###
自定义ObjectMapper
如果很多类中都定义了Date
类的属性,则需要在每个类中添加JsonFormat(pattern="")
来实现时间格式化,这样就会变得很麻烦,代码也会显得很臃肿。因此,可以自定义一个ObjectMapper
,用于修饰Date
类型的属性。
- com.jepcc.example.pojo.Student
package com.jepcc.example.pojo;
import java.util.Date;
public class Student {
private String id;
private String name;
private int age;
private String gender;
private Date birthday;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
@Override
public String toString() {
final StringBuffer sb = new StringBuffer("Student{");
sb.append("id='").append(id).append('\'');
sb.append(", name='").append(name).append('\'');
sb.append(", age=").append(age);
sb.append(", gender='").append(gender).append('\'');
sb.append(", birthday=").append(birthday);
sb.append('}');
return sb.toString();
}
}
- com.jepcc.example.config.ObjectMapperConfig
注意两点:
1)添加注解@Configuration
,标识ObjectMapperConfig
为一个配置类
2)添加注解@Bean
,将自定义的ObjectMapper
注入SpringBoot的IOC容器。
package com.jepcc.example.config;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.text.SimpleDateFormat;
@Configuration
public class ObjectMapperConfig {
@Bean
public ObjectMapper getObjectMapper(){
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
return objectMapper;
}
}
- com.jepcc.example.controller.StudentController
注意一点:将自定义的ObjectMapper
通过注解@Autowired
引入并使用。
package com.jepcc.example.controller;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.jepcc.example.pojo.Student;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Date;
@RestController
@RequestMapping("/test")
public class StudentController {
@Autowired
private ObjectMapper mapper;
@GetMapping("/pojo2string")
public String test() throws JsonProcessingException {
Student stu = new Student();
stu.setId("1");
stu.setName("Nicholas");
stu.setAge(18);
stu.setGender("male");
stu.setBirthday(new Date());
String str = mapper.writeValueAsString(stu);
return str;
}
@GetMapping("/string2pojo")
public Student convert() throws JsonProcessingException {
String str = "{\"id\":\"10\",\"name\":\"Lucy\",\"age\":20,\"gender\":\"female\",\"birthday\":"+new Date().getTime()+"}";
Student stu = mapper.readValue(str,Student.class);
return stu;
}
}
- 调用接口进行测试验证
GET http://localhost:8000/test/pojo2string
Content-Type: application/json
###
GET http://localhost:8000/test/string2pojo
Content-Type: application/json
###
使用lombok
- com.jepcc.example.pojo.Student
package com.jepcc.example.pojo;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Date;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class Student {
private String id;
private String name;
private int age;
private String gender;
private Date birthday;
}
- com.jepcc.example.controller.StudentController
package com.jepcc.example.controller;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.jepcc.example.pojo.Student;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Date;
@RestController
@RequestMapping("/test")
public class StudentController {
@Autowired
private ObjectMapper mapper;
@GetMapping("/pojo2string")
public String test() throws JsonProcessingException {
Student stu = Student.builder()
.id("1")
.name("Nicholas")
.age(18)
.gender("male")
.birthday(new Date())
.build();
String str = mapper.writeValueAsString(stu);
return str;
}
@GetMapping("/string2pojo")
public Student convert() throws JsonProcessingException {
String str = "{\"id\":\"10\",\"name\":\"Lucy\",\"age\":20,\"gender\":\"female\",\"birthday\":"+new Date().getTime()+"}";
Student stu = mapper.readValue(str,Student.class);
return stu;
}
}
- com.jepcc.example.config.ObjectMapperConfig
package com.jepcc.example.config;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.text.SimpleDateFormat;
@Configuration
public class ObjectMapperConfig {
@Bean
public ObjectMapper getObjectMapper(){
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
return objectMapper;
}
}
- 调用接口进行测试和验证
GET http://localhost:8000/test/pojo2string
Content-Type: application/json
###
GET http://localhost:8000/test/string2pojo
Content-Type: application/json
###
lombok注解之@Data
注解@Data
作用在类上,会为类的所有属性自动生成setter/getter
、equals
、hasCode
、toString
方法。更多可以访问这里和这里。
lombok注解之@Builder
@Builder
在创建对象时具有链式赋值的特点。更多可以访问这里。
参考文章
SpringBoot基础篇(一)默认转换工具Jackson
Lombok官网
reducing boilerplate code with project lombok
Lombok注解系列文章总览
Lombok介绍、使用方法和总结
06. 《Lombok 实战 —— @Builder》