基本介绍
Spring Boot提供了与三个JSON映射库的集成:Gson、Jackson、JSON-B
。其中,Jackson是首选的默认库。
Jackson不仅支持流式处理json,还支持数据绑定(对象和JSON之间的相互转化,即序列化和反序列化)
Jackson的三个核心模块:
jackson-core
: 定义了低级的流式API,包括JSON处理细节jackson-annotations
: 包含了Jackson的注解jackson-databind
: 实现了对象和JSON之间的转换,这个包依赖上面两个包
Jackson中常用的类:
JsonFactory
:Jackson主要的工厂方法,用于配置和构建生成器(如JsonGenerator)和解析器(JsonParser)
JsonGenerator
:生成Json格式的内容,可使用JsonFactory 的方法生成一个实例
JsonParser
:读取Json格式的内容,并且完成解析操作,可使用JsonFactory的方法生成一个实例
ObjectMapper
:提供了Java对象和Json之间的转化,主要通过JsonParser和JsonGenerator实例来完成对Json数据的读写操作
处理JSON的三种方法:
-
数据绑定:使用属性访问器或注解在JSON与普通Java对象之间进行转换。ObjectMapper提供了读/写几种数据类型绑定的JSON的方法。这是最方便的方法。
-
JSON树模型 :把JSON在内存构建成为树状结构,即JsonNode节点的ObjectMapper构建树。这是最灵活的方法。
-
数据流API:读取和写入JSON内容作为离散事件。JsonParser读取数据,而JsonGenerator写入数据。这是功能最强大的一种,开销最低,读/写操作最快。
在springboot中使用Jackson
引入maven
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.10.2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.10.2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.10.2</version>
</dependency>
开始使用
public void test() throws JsonProcessingException {
ObjectMapper objectMapper = new ObjectMapper();
User user = new User();
user.setId(100);
user.setName("zhangsan");
user.setDescription("张三喜欢编程");
user.setMobile("18812344321");
String jsonStr = objectMapper.writeValueAsString(user);
System.out.println("Java对象转换为Json字符串:\n" + jsonStr);
User object = objectMapper.readValue(jsonStr, User.class);
System.out.println("Json字符串转换为Java对象:\n" + object);
}
Jackson在springboot中的常用注解
@JsonProperty
-
字段
-
为字段指定一个别名,将该字段的名称在序列化和反序列化中以该名称显示,将表结构中的字段映射到实体类中
@JsonProperty("user_name")
private String userName;
@JsonAlias
- 字段
- 指定该属性可以接受多个Json字段的名称,只在反序列化时起作用
@JsonAlias({
"name","user"})
private String username;
@JsonIgnore
- 字段
- 在Json转换时忽略该字段
@JsonIgnore
private String username;
@JsonIgnoreProperties
- 实体类
- 在Json转换时忽略多个属性,JsonIgnoreProperties(ignoreUnknown=true)忽略未知属性
@JsonIgnoreProperties({
"description","mobile"})
@Data
public class User {
private Integer id;
private String name;
private String description;
private String mobile;
}
@JsonFormat
- 字段
- 格式化时间类型数据传输时的格式
@JsonFormat(pattern="yyyy-MM-dd",timezone = "GMT+8")
//pattern是想要转换的日期格式,timezone是时间设置为东八区,避免时间在转换中差8个小时
private Date date;
注:@JsonFormat和@DateTimeFormat区别?
@JsonFormat
:是Jackson在springboot中的注解,用来格式化时间类型数据传输时的格式,也可以设置时区,避免时间展示与想要的结果产生误差。
@DateTimeFormat
:是Spring自带的注解,用来将前端传来的字符串类型的日期转为后台需要的时间类型结果,不加此注解,请求会报错400,请求参数错误,对于此类错误要注意int类型数据传输也是一样。
@JsonInclude
- 实体类
- 指定实体类在序列化时的策略
策略参数枚举类如下:
public enum Include
{
/**
* 序列化所有属性
*/
ALWAYS,
/**
* 序列化非null属性
*/
NON_NULL,
/**
* 序列化非null或者引用类型缺省值,例如java8的Optional类,通常与Optional一起使用
*
* @since 2.6
*/
NON_ABSENT,
/**
* 序列化非Empty的属性,例如空集合不会被序列化
*/
NON_EMPTY,
/**
* 仅包含与实体类属性默认值不同的值
*/
NON_DEFAULT,
/**
* 由{@link JsonInclude#valueFilter}指定值本身,或由{@link JsonInclude#contentFilter}指定结构化类型的内容
* 由过滤器对象的equals方法进行序列化,返回true则会被排除,返回false会被序列化
*
* @since 2.9
*/
CUSTOM,
/**
* 使用默认值
*
* @since 2.6
*/
USE_DEFAULTS
;
}
如:指定实体类序列化时使用NON_NULL策略
@JsonInclude(JsonInclude.Include.NON_NULL)
@Data
public class User {
private Integer id;
private String name;
private String description;
private String mobile;
}
public void testJsonInclude() throws JsonProcessingException {
ObjectMapper objectMapper = new ObjectMapper();
User user = new User();
user.setId(1000);
user.setName("小红");
System.out.println(objectMapper.writeValueAsString(user));
}
// console
{
"id":1000,"name":"小红"}
以上,指定NON_NULL策略,序列化后只包含非空属性。
@JsonSerialize
- 实体类、属性
- 指定要使用的Serializer,一般会使用自定义的序列化器(具体例子见 自定义JsonSerializer)
@JacksonInject
- 属性
- 反序列化时可以将没有的字段设置为我们设置好的默认值
@JacksonInject(value= "defaultUsername", useInput= OptBoolean.FALSE)
private String username;
@JsonPropertyOrder
- 实体类
- 序列化时对字段进行排序
@JsonPropertyOrder({
"description", "name", "id", "mobile"})
@Data
public class User {
private Integer id;
private String name;
private String description;
private String mobile;
}
@JsonValue
- 字段、get方法
- 只序列化这个字段的值
@Data
public class User {
private Integer id;
@JsonValue
private String name;
private String description;
private String mobile;
}
@JsonRootName
- 实体类
- 定义一个根key
@JsonRootName(value