本案例基于 Springboot 2.5.7 单元测试场景下进行

<!-- SpringMVC默认使用Jacson,只需要引用web启动器即可,无序单独引用Jackson -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Springboot单元测试 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<!-- Lombok工具类 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!-- Hutool工具类 -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.3</version>
</dependency>

在后面的测试中会用到的实体类

@Data
@NoArgsConstructor
@AllArgsConstructor
public class UserEntity {
private Integer id;
private String username;
private String password;
private Date birthday;
private LocalDateTime lastLoginDate;
private DeptEntity dept;
}
@Data
@NoArgsConstructor
@AllArgsConstructor
public class DeptEntity {
private Integer id;
private String name;
}
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Result<T> { private int code;
private String msg;
private T data; public static <T> Result<T> success(T data) {
return new Result<>(200, "请求成功", data);
} }

IOC 容器中可以直接获取到 Jackson 的 ObjectMapper 实例

@SpringBootTest
public class SpringTest {
@Autowired
private ObjectMapper mapper;
}

基础类型转换

简单来说就是实体类转换,无论是实体类还是实体类嵌套方法都是一样的

实体类转换

@Test
void test() throws JsonProcessingException {
// 实体类
DeptEntity dept = new DeptEntity(10001, "部门A");
// 序列化
String json = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(dept);
// 反序列化
System.out.println(mapper.readValue(json, DeptEntity.class));
}

实体类嵌套转换

@Test
void test() {
// 实体类
Date birthday = new Date();
LocalDateTime lastLoginDate = LocalDateTime.now();
DeptEntity dept = new DeptEntity(10001, "部门A");
UserEntity user = new UserEntity(10001, "用户A", null, birthday, lastLoginDate, dept);
// 序列化
String json = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(user);
// 反序列化
System.out.println(mapper.readValue(json, UserEntity.class));
}

集合类型转换

集合转换简单了解这两种就够了,复杂一点的后面会提到

Collection 集合转换

@Test
void test() throws JsonProcessingException {
// 构建List集合
List<DeptEntity> source = CollUtil.newArrayList();
for (int i = 1; i <= 5; i++) {
source.add(new DeptEntity(10000 + i, "用户" + i));
}
// 序列化
String json = mapper.writeValueAsString(source);
// 构建Type对象
CollectionType type = mapper.getTypeFactory().constructCollectionType(List.class, DeptEntity.class);
// 反序列化
List<DeptEntity> target = mapper.readValue(json, type);
System.out.println(target);
}

Map 集合转换

@Test
void test() throws JsonProcessingException {
// 构建List集合
Map<String, String> source = MapUtil.newHashMap();
source.put("aaa", "哈哈");
source.put("bbb", "呵呵");
// 序列化
String json = mapper.writeValueAsString(source);
// 构建Type对象
MapLikeType type = mapper.getTypeFactory().constructMapLikeType(HashMap.class, String.class, String.class);
// 反序列化
Map<String, String> target = mapper.readValue(json, type);
System.out.println(target);
}

复杂类型转换

这个部分的功能掌握了,类型转换就基本没啥问题了

带有泛型的序列化

@Test
void test() throws JsonProcessingException {
// 实体类
Result<DeptEntity> source = Result.success(new DeptEntity(10001, "部门A"));
// 序列化
String json = mapper.writeValueAsString(source);
// 构建Type对象
JavaType type = mapper.getTypeFactory().constructParametricType(Result.class, DeptEntity.class);
// 反序列化
Result<DeptEntity> target = mapper.readValue(json, type);
System.out.println(target.getData().getClass());
System.out.println(target);
}

泛型嵌套的序列化

@Test
void test() throws JsonProcessingException {
String key = "res";
// 重头戏来了 泛型嵌套的List集合
List<Map<String, Result<DeptEntity>>> source = CollUtil.newArrayList();
Map<String, Result<DeptEntity>> map = MapUtil.newHashMap();
Result<DeptEntity> res = Result.success(new DeptEntity(10001, "部门A"));
map.put(key, res);
source.add(map);
// 序列化
String json = mapper.writeValueAsString(source);
// 构建Type对象
SimpleType stringType = SimpleType.constructUnsafe(String.class);
JavaType result = mapper.getTypeFactory().constructParametricType(Result.class, DeptEntity.class);
MapLikeType mapType = mapper.getTypeFactory().constructMapLikeType(HashMap.class, stringType, result);
CollectionType type = mapper.getTypeFactory().constructCollectionType(List.class, mapType);
// 反序列化
List<Map<String, Result<DeptEntity>>> target = mapper.readValue(json, type);
System.out.println(target.get(0).get(key).getData().getClass());
System.out.println(target.get(0).get(key).getClass());
System.out.println(target.get(0).getClass());
System.out.println(target.getClass());
System.out.println(target);
}

Jackson 的配置项

常见的用法是把 Controller 回传给前端的 JSON 进行一些处理,例如时间格式化、忽略 NULL 值等等

这些配置可以在配置文件中完成,可以重新注入ObjectMapper,也可以使用实体类注解单独配置

这部分内容用到哪些配置项,想起来就补充,随缘更新

配置文件

spring:
jackson:
# 格式化日期时使用的时区
time-zone: GMT+8
# 格式化
date-format: yyyy-MM-dd HH:mm:ss.SSS
# 用于格式化的语言环境
locale: zh_CN
serialization:
# 是否开启格式化输出
indent_output: false

重新注入 ObjectMapper

@Bean
public ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder) {
// 通过该方法对mapper对象进行设置,所有序列化的对象都将该规则进行序列化
ObjectMapper objectMapper = builder.createXmlMapper(false).build();
// Include.Include.ALWAYS 默认
// Include.NON_DEFAULT 属性为默认值不序列化
// Include.NON_EMPTY 属性为 空("") 或者为 NULL 都不序列化,则返回的json是没有这个字段的。这样对移动端会更省流量
// Include.NON_NULL 属性为NULL 不序列化
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
return objectMapper;
}

实体类注解

注解 作用
@JsonIgnoreProperties 批量设置转 JSON 时忽略的属性
@JsonIgnore 转 JSON 时忽略当前属性
@JsonProperty 修改转换后的 JSON 的属性名
@JsonFormat 转 JSON 时格式化属性的值

Springboot JSON 转换:Jackson篇的更多相关文章

  1. @JsonCreator自定义反序列化函数-JSON框架Jackson精解第5篇

    Jackson是Spring Boot(SpringBoot)默认的JSON数据处理框架,但是其并不依赖于任何的Spring 库.有的小伙伴以为Jackson只能在Spring框架内使用,其实不是的, ...

  2. Jackson框架,json转换

    Jackson可以轻松的将Java对象转换成json对象和xml文档,同样也可以将json.xml转换成Java对象. 前面有介绍过json-lib这个框架,在线博文:http://www.cnblo ...

  3. Springboot单例模式实战封装json转换

    一.定义 保证一个类仅有一个实例,并提供一个全局访问点. 二.优点 (1)在内存里只有一个实例,减少了内存开销      (2)可以避免对资源的多重占用      (3)设置全局访问点,严格控制访问 ...

  4. 【Json】Jackson将json转换成泛型List

    Jackson将json转换成泛型List 获取泛型类型 /** * 获取泛型类型 * * @return */ protected Class<T> getGenericsType() ...

  5. Spring学习---Spring中利用jackson进行JSON转换

    Spring中利用jackson进行JSON转换 import java.util.List; import com.fasterxml.jackson.core.JsonProcessingExce ...

  6. URL及日期等特殊数据格式处理-JSON框架Jackson精解第2篇

    Jackson是Spring Boot默认的JSON数据处理框架,但是其并不依赖于任何的Spring 库.有的小伙伴以为Jackson只能在Spring框架内使用,其实不是的,没有这种限制.它提供了很 ...

  7. 属性序列化自定义与字母表排序-JSON框架Jackson精解第3篇

    Jackson是Spring Boot默认的JSON数据处理框架,但是其并不依赖于任何的Spring 库.有的小伙伴以为Jackson只能在Spring框架内使用,其实不是的,没有这种限制.它提供了很 ...

  8. Springboot中redisTemplate乱码或json转换问题

    问题1 用RedisTemplate存入map值的时候,用rdm可视化打开,看到的是转码之后的数据,如图: 存入的方法为: public boolean hmset(String key, Map&l ...

  9. java json转换

    https://blog.csdn.net/WillJGL/article/details/77866224 SpringBoot中如果需要实现json的序列化和反序列化,我们会使用json解析工具. ...

随机推荐

  1. 用 Antlr 重构脚本解释器

    前言 在上一个版本实现的脚本解释器 GScript 中实现了基本的四则运算以及 AST 的生成. 当我准备再新增一个 % 取模的运算符时,会发现工作很繁琐而且几乎都是重复的:主要是两步: 需要在词法解 ...

  2. 从 Airflow 到 Apache DolphinScheduler,有赞大数据开发平台的调度系统演进

    点击上方 蓝字关注我们 作者 | 宋哲琦 ✎ 编 者 按 在不久前的 Apache  DolphinScheduler Meetup 2021 上,有赞大数据开发平台负责人 宋哲琦 带来了平台调度系统 ...

  3. 【沥血整理】灰度(二值)图像重构算法及其应用(morphological reconstruction)。

    不记得是怎么接触并最终研究这个课题的了,认识我的人都知道我是没有固定的研究对象的,一切看运气和当时的兴趣.本来研究完了就放在那里了,一直比较懒的去做总结,但是想一想似乎在网络上就没有看到关于这个方面的 ...

  4. JVM 系列(4)一看就懂的对象内存布局

    请点赞关注,你的支持对我意义重大. Hi,我是小彭.本文已收录到 GitHub · AndroidFamily 中.这里有 Android 进阶成长知识体系,有志同道合的朋友,关注公众号 [彭旭锐] ...

  5. BZOJ4337 树的同构 (树哈希)(未完成)

    样例迷,没过 交了30pts #include <cstdio> #include <iostream> #include <cstring> #include & ...

  6. python推导式与海象运算符

    背景:介绍两种python用于语句优化的用法 一.推导式 1.推导式简介: Python 推导式是一种独特的数据处理方式,可以从一个数据序列构建另一个新的数据序列的结构体. 支持:列表(list).元 ...

  7. mongo数据同步的三种方案

    (一)直接复制data目录(需要停止源和目标的mongo服务)1.针对目标mongo服务已经存在,并正在运行的(mongo2-->mongo).执行步骤:(1).停止源/目标服务器的mongo服 ...

  8. jQuery 判断父节点下是否有子节点

    查找父节点下是否有子节点有两个情况:(1)查找的是父元素的所有后代节点:(2)仅查找父元素的第一代子节点. <div id="app"> <div> < ...

  9. 【java】学习路线8-cmd带命令编译包

    /*java类包(package)package XX.XX.XX;    包名命名规则:(以域名开头,都是小写)        com.remooo.xx        编译:javac -d . ...

  10. Android的Handler线程切换原理

    Handler是我们在开发中经常会接触到的类,因为在Android中,子线程一般是不能更新UI的. 所以我们会使用Handler切换到主线程来更新UI,那Handler是如何做到实现不同线程之间的切换 ...