Jackson基本使用
【摘要】 1. 序列化 1.1 只包含非 null 属性 1.1.1 全局配置 1.1.2 单个 bean 配置 1.2 日期时间格式化 1.2.1 全局配置 1.2.2 单个 bean 配置 1.3 序列化的美化输出 2. 反序列化 2.1 忽略不存在的 key 2.2 泛型的处理 3. 通用配置 3.1 驼峰转下划线和下划线转驼峰 3.2 指定属性名和JSON字符串中Key对应的关系 3.3 忽...
- 导入Jackson所需的依赖
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.10.1</version>
</dependency>
<!--对localDateTime等jdk8时间日期api的转换支持-->
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>2.10.1</version>
</dependency>
- 可以看到 jsr310 依赖是包含 databind 依赖的
1. 序列化
1.1 只包含非 null 属性
- 默认是包含 null
@Test
public void test1() throws JsonProcessingException {
Person person = new Person();
person.setId(1);
// person.setName("兮动人");
person.setAge(20);
person.setBirthDate(new Date());
person.setAddress("深圳市");
String s = objectMapper.writeValueAsString(person);
System.out.println(s);
}
1.1.1 全局配置
- 配置不包含 null,全局配置
private static ObjectMapper objectMapper = new ObjectMapper();
static {
/**
* 序列化的配置
*/
// 全局配置:配置序列化时只包含非空属性
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
}
/**
* 序列化
*/
@Test
public void test1() throws JsonProcessingException {
Person person = new Person();
person.setId(1);
// person.setName("兮动人");
person.setAge(20);
person.setBirthDate(new Date());
person.setAddress("深圳市");
String s = objectMapper.writeValueAsString(person);
System.out.println(s);
}
1.1.2 单个 bean 配置
- 单个 bean 配置指定非空
1.2 日期时间格式化
@Data
public class Person {
private Integer id;
private String name;
private Integer age;
private String address;
private boolean flag;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date birthDate;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private LocalDateTime registerDate;
}
private static ObjectMapper objectMapper = new ObjectMapper();
static {
/**
* 序列化的配置
*/
// 配置序列化时只包含非空属性
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
}
/**
* 序列化
*/
@Test
public void test1() throws JsonProcessingException {
Person person = new Person();
person.setId(1);
person.setName("兮动人");
person.setAge(20);
person.setBirthDate(new Date());
person.setAddress("深圳市");
person.setRegisterDate(LocalDateTime.now());
String s = objectMapper.writeValueAsString(person);
System.out.println(s);
}
- 可以看到只有 Date birthDate 属性转换成功了,LocalDateTime registerDate 格式是没有转换的
1.2.1 全局配置
- 加上 全局配置:自动通过spi发现 Jackson 的module并注册
static {
/**
* 序列化的配置
*/
// 配置序列化时只包含非空属性
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
/**
* 全局配置:自动通过spi发现 Jackson 的module并注册
*
*/
objectMapper.findAndRegisterModules();
}
1.2.2 单个 bean 配置
- 手动配置
private static ObjectMapper objectMapper = new ObjectMapper();
private static final String DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
static {
/**
* 序列化的配置
*/
// 配置序列化时只包含非空属性
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
/**
* 全局配置:自动通过spi发现 Jackson 的module并注册
*/
// objectMapper.findAndRegisterModules();
//手动配置 JavaTimeModule 并注册
JavaTimeModule javaTimeModule = new JavaTimeModule();
// 序列化
javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DATE_TIME_FORMAT)));
// 反序列化
javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DATE_TIME_FORMAT)));
// 注册
objectMapper.registerModule(javaTimeModule);
}
- 可以看到 LocalDateTime 类型也可以通过手动配置的方式实现格式化效果
1.3 序列化的美化输出
// 序列化的美化输出
objectMapper.configure(SerializationFeature.INDENT_OUTPUT, true);
2. 反序列化
2.1 忽略不存在的 key
private static ObjectMapper objectMapper = new ObjectMapper();
@Test
public void test2() throws JsonProcessingException {
String str = "{\n" +
" \"id\" : 1,\n" +
" \"name\" : \"兮动人\",\n" +
" \"age\" : 20,\n" +
" \"address\" : \"深圳市\",\n" +
" \"flag\" : false,\n" +
" \"birthDate\" : \"2022-10-09 15:29:56\",\n" +
" \"registerDate\" : \"2022-10-09 15:29:56\"\n" +
"}";
Person person = objectMapper.readValue(str, Person.class);
System.out.println(person);
}
-
如果在JSON字符串中加入个没有定义的属性,就会报错找不到这个属性
-
设置 忽略 不存在的属性,两种写法都可以
// 设置 忽略 不存在的属性
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
- 在 fastjson 中,默认就会忽略这些不存在的 key
2.2 泛型的处理
@Data
public class ResultDTO<T> {
private Boolean success = Boolean.TRUE;
private T data;
private ResultDTO(){}
public static <T> ResultDTO<T> buildSuccess(T t) {
ResultDTO<T> result = new ResultDTO<>();
result.setData(t);
return result;
}
}
- 输出经过泛型处理的结果和泛型里的 Person 对象
/**
* 泛型的处理
*/
@Test
public void test3() throws JsonProcessingException {
Person person = new Person();
person.setName("xdr");
person.setAddress("深圳");
ResultDTO<Person> personResultDTO = ResultDTO.buildSuccess(person);
String s = objectMapper.writeValueAsString(personResultDTO);
// 反序列化为 ResultDTO<Person>
ResultDTO<Person> dataResult = objectMapper.readValue(s, new TypeReference<ResultDTO<Person>>() {
});
System.out.println("dataResult: " + dataResult);
System.out.println("data: " + dataResult.getData()); // 输出里面的 Person
}
3. 通用配置
- 指序列化或反序列化的时候都可以使用
3.1 驼峰转下划线和下划线转驼峰
- 全局配置:
1、序列化:驼峰转下划线
// 驼峰转下划线 userName -> user_name
objectMapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
/**
* 序列化
*/
@Test
public void test1() throws JsonProcessingException {
Person person = new Person();
person.setId(1);
person.setName("兮动人");
person.setAge(20);
person.setBirthDate(new Date());
person.setAddress("深圳市");
person.setRegisterDate(LocalDateTime.now());
String s = objectMapper.writeValueAsString(person);
System.out.println(s);
}
2、反序列化:下划线转驼峰
/**
* 反序列化
*/
@Test
public void test2() throws JsonProcessingException {
String str = "{\n" +
" \"id\" : 1,\n" +
" \"name\" : \"兮动人\",\n" +
" \"age\" : 20,\n" +
" \"address\" : \"深圳市\",\n" +
" \"flag\" : false,\n" +
" \"birth_date\" : \"2022-10-18 20:01:32\",\n" +
" \"register_date\" : \"2022-10-18 20:01:32\"\n" +
"}\n";
Person person = objectMapper.readValue(str, Person.class);
System.out.println(person);
}
3.2 指定属性名和JSON字符串中Key对应的关系
-
指定属性名,相当于给属性别名
-
序列化输出后,就是指定的别名
-
把上面JSON字符串反序列化后,输出的就是对应的 address 属性值
3.3 忽略指定属性
-
忽略 age 属性,默认为 true
-
序列化后就没有这个值输出了
-
反序列后即便传了 age 属性,也不会进行赋值处理
4. 利用 Jackson 做对象的更新
- 对象更新:对象的合并/重写,如果后者的对象有值,则用后者的,否则前者的值不变
/**
* 对象的更新
*/
@Test
public void test4() throws JsonMappingException {
Person person1 = new Person();
person1.setId(22);
person1.setName("xdr");
person1.setAddress("深圳 ");
Person person2 = new Person();
person2.setId(33);
Person person = objectMapper.updateValue(person1, person2);
System.out.println(person);
}
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)