Spring Boot 默认对Json的处理

简介: 本文详解Spring Boot中JSON处理,涵盖Jackson与FastJson的使用对比、null值处理及统一返回结构封装,提升接口数据规范性与可读性。

在实际项目中,常用的数据结构无非有类对象、List对象、Map对象,我们看一下默认的 jackson 框架对这三个常用的数据结构转成 json 后的格式如何。

1.1 创建 User 实体类

为了测试,我们需要创建一个实体类,这里我们就用 User 来演示。

public class User {

  private Long id;

  private String username;

  private String password;

   /* 省略get、set和带参构造方法 */

}

1.2 创建Controller类

然后我们创建一个 Controller,分别返回 User对象、List<User>Map<String, Object>

import com.itcodai.course02.entity.User;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;

import java.util.HashMap;

import java.util.List;

import java.util.Map;

@RestController

@RequestMapping("/json")

public class JsonController {

  @RequestMapping("/user")

  public User getUser() {

      return new User(1, "倪升武", "123456");

   }

  @RequestMapping("/list")

  public List<User> getUserList() {

      List<User> userList = new ArrayList<>();

      User user1 = new User(1, "倪升武", "123456");

      User user2 = new User(2, "达人课", "123456");

      userList.add(user1);

      userList.add(user2);

      return userList;

   }

  @RequestMapping("/map")

  public Map<String, Object> getMap() {

      Map<String, Object> map = new HashMap<>(3);

      User user = new User(1, "倪升武", "123456");

      map.put("作者信息", user);

      map.put("博客地址", "http://blog.itcodai.com");

      map.put("CSDN地址", "http://blog.csdn.net/eson_15");

      map.put("粉丝数量", 4153);

      return map;

   }

}

1.3 测试不同数据类型返回的json

OK,写好了接口,分别返回了一个 User 对象、一个 List 集合和一个 Map 集合,其中 Map 集合中的 value 存的是不同的数据类型。接下来我们依次来测试一下效果。

在浏览器中输入:localhost:8080/json/user 返回 json 如下:

{"id":1,"username":"倪升武","password":"123456"}

在浏览器中输入:localhost:8080/json/list 返回 json 如下:

[{"id":1,"username":"倪升武","password":"123456"},{"id":2,"username":"达人课","password":"123456"}]

在浏览器中输入:localhost:8080/json/map 返回 json 如下:

{"作者信息":{"id":1,"username":"倪升武","password":"123456"},"CSDN地址":"http://blog.csdn.net/eson_15","粉丝数量":4153,"博客地址":"http://blog.itcodai.com"}

可以看出,map 中不管是什么数据类型,都可以转成相应的 json 格式,这样就非常方便。

1.4 jackson 中对null的处理

在实际项目中,我们难免会遇到一些 null 值出现,我们转 json 时,是不希望有这些 null 出现的,比如我们期望所有的 null 在转 json 时都变成 "" 这种空字符串,那怎么做呢?在 Spring Boot 中,我们做一下配置即可,新建一个 jackson 的配置类:

import com.fasterxml.jackson.core.JsonGenerator;

import com.fasterxml.jackson.databind.JsonSerializer;

import com.fasterxml.jackson.databind.ObjectMapper;

import com.fasterxml.jackson.databind.SerializerProvider;

import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

import org.springframework.context.annotation.Primary;

import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;

import java.io.IOException;

@Configuration

public class JacksonConfig {

  @Bean

  @Primary

  @ConditionalOnMissingBean(ObjectMapper.class)

  public ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder) {

      ObjectMapper objectMapper = builder.createXmlMapper(false).build();

      objectMapper.getSerializerProvider().setNullValueSerializer(new JsonSerializer<Object>() {

          @Override

          public void serialize(Object o, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {

              jsonGenerator.writeString("");

           }

       });

      return objectMapper;

   }

}

然后我们修改一下上面返回 map 的接口,将几个值改成 null 测试一下:

@RequestMapping("/map")

public Map<String, Object> getMap() {

  Map<String, Object> map = new HashMap<>(3);

  User user = new User(1, "倪升武", null);

  map.put("作者信息", user);

  map.put("博客地址", "http://blog.itcodai.com");

  map.put("CSDN地址", null);

  map.put("粉丝数量", 4153);

  return map;

}

重启项目,再次输入:localhost:8080/json/map,可以看到 jackson 已经将所有 null 字段转成了空字符串了。

{"作者信息":{"id":1,"username":"倪升武","password":""},"CSDN地址":"","粉丝数量":4153,"博客地址":"http://blog.itcodai.com"}

2. 使用阿里巴巴FastJson的设置

2.1 jackson 和 fastJson 的对比

有很多朋友习惯于使用阿里巴巴的 fastJson 来做项目中 json 转换的相关工作,目前我们项目中使用的就是阿里的 fastJson,那么 jackson 和 fastJson 有哪些区别呢?根据网上公开的资料比较得到下表。

选项

fastJson

jackson

上手难易程度

容易

中等

高级特性支持

中等

丰富

官方文档、Example支持

中文

英文

处理json速度

略快

关于 fastJson 和 jackson 的对比,网上有很多资料可以查看,主要是根据自己实际项目情况来选择合适的框架。从扩展上来看,fastJson 没有 jackson 灵活,从速度或者上手难度来看,fastJson 可以考虑,我们项目中目前使用的是阿里的 fastJson,挺方便的。

2.2 fastJson依赖导入

使用 fastJson 需要导入依赖,本课程使用 1.2.35 版本,依赖如下:

<dependency>

   <groupId>com.alibaba</groupId>

   <artifactId>fastjson</artifactId>

   <version>1.2.35</version>

</dependency>

2.2 使用 fastJson 处理 null

使用 fastJson 时,对 null 的处理和 jackson 有些不同,需要继承  WebMvcConfigurationSupport 类,然后覆盖 configureMessageConverters 方法,在方法中,我们可以选择对要实现 null 转换的场景,配置好即可。如下:

import com.alibaba.fastjson.serializer.SerializerFeature;

import com.alibaba.fastjson.support.config.FastJsonConfig;

import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;

import org.springframework.context.annotation.Configuration;

import org.springframework.http.MediaType;

import org.springframework.http.converter.HttpMessageConverter;

import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;

import java.nio.charset.Charset;

import java.util.ArrayList;

import java.util.List;

@Configuration

public class fastJsonConfig extends WebMvcConfigurationSupport {

  /**

   * 使用阿里 FastJson 作为JSON MessageConverter

   * @param converters

   */

  @Override

  public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {

      FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter();

      FastJsonConfig config = new FastJsonConfig();

      config.setSerializerFeatures(

              // 保留map空的字段

              SerializerFeature.WriteMapNullValue,

              // 将String类型的null转成""

              SerializerFeature.WriteNullStringAsEmpty,

              // 将Number类型的null转成0

              SerializerFeature.WriteNullNumberAsZero,

              // 将List类型的null转成[]

              SerializerFeature.WriteNullListAsEmpty,

              // 将Boolean类型的null转成false

              SerializerFeature.WriteNullBooleanAsFalse,

              // 避免循环引用

              SerializerFeature.DisableCircularReferenceDetect);

      converter.setFastJsonConfig(config);

      converter.setDefaultCharset(Charset.forName("UTF-8"));

      List<MediaType> mediaTypeList = new ArrayList<>();

      // 解决中文乱码问题,相当于在Controller上的@RequestMapping中加了个属性produces = "application/json"

      mediaTypeList.add(MediaType.APPLICATION_JSON);

      converter.setSupportedMediaTypes(mediaTypeList);

      converters.add(converter);

   }

}

3. 封装统一返回的数据结构

以上是 Spring Boot 返回 json 的几个代表的例子,但是在实际项目中,除了要封装数据之外,我们往往需要在返回的 json 中添加一些其他信息,比如返回一些状态码 code ,返回一些 msg 给调用者,这样调用者可以根据 code 或者 msg 做一些逻辑判断。所以在实际项目中,我们需要封装一个统一的 json 返回结构存储返回信息。

3.1 定义统一的 json 结构

由于封装的 json 数据的类型不确定,所以在定义统一的 json 结构时,我们需要用到泛型。统一的 json 结构中属性包括数据、状态码、提示信息即可,构造方法可以根据实际业务需求做相应的添加即可,一般来说,应该有默认的返回结构,也应该有用户指定的返回结构。如下:

public class JsonResult<T> {

  private T data;

  private String code;

  private String msg;

  /**

   * 若没有数据返回,默认状态码为0,提示信息为:操作成功!

   */

  public JsonResult() {

      this.code = "0";

      this.msg = "操作成功!";

   }

  /**

   * 若没有数据返回,可以人为指定状态码和提示信息

   * @param code

   * @param msg

   */

  public JsonResult(String code, String msg) {

      this.code = code;

      this.msg = msg;

   }

  /**

   * 有数据返回时,状态码为0,默认提示信息为:操作成功!

   * @param data

   */

  public JsonResult(T data) {

      this.data = data;

      this.code = "0";

      this.msg = "操作成功!";

   }

  /**

   * 有数据返回,状态码为0,人为指定提示信息

   * @param data

   * @param msg

   */

  public JsonResult(T data, String msg) {

      this.data = data;

      this.code = "0";

      this.msg = msg;

   }

  // 省略get和set方法

}

3.2 修改 Controller 中的返回值类型及测试

由于 JsonResult 使用了泛型,所以所有的返回值类型都可以使用该统一结构,在具体的场景将泛型替换成具体的数据类型即可,非常方便,也便于维护。在实际项目中,还可以继续封装,比如状态码和提示信息可以定义一个枚举类型,以后我们只需要维护这个枚举类型中的数据即可(在本课程中就不展开了)。根据以上的 JsonResult,我们改写一下 Controller,如下:

@RestController

@RequestMapping("/jsonresult")

public class JsonResultController {

  @RequestMapping("/user")

  public JsonResult<User> getUser() {

      User user = new User(1, "倪升武", "123456");

      return new JsonResult<>(user);

   }

  @RequestMapping("/list")

  public JsonResult<List> getUserList() {

      List<User> userList = new ArrayList<>();

      User user1 = new User(1, "倪升武", "123456");

      User user2 = new User(2, "达人课", "123456");

      userList.add(user1);

      userList.add(user2);

      return new JsonResult<>(userList, "获取用户列表成功");

   }

  @RequestMapping("/map")

  public JsonResult<Map> getMap() {

      Map<String, Object> map = new HashMap<>(3);

      User user = new User(1, "倪升武", null);

      map.put("作者信息", user);

      map.put("博客地址", "http://blog.itcodai.com");

      map.put("CSDN地址", null);

      map.put("粉丝数量", 4153);

      return new JsonResult<>(map);

   }

}

我们重新在浏览器中输入:localhost:8080/jsonresult/user 返回 json 如下:

{"code":"0","data":{"id":1,"password":"123456","username":"倪升武"},"msg":"操作成功!"}

输入:localhost:8080/jsonresult/list,返回 json 如下:

{"code":"0","data":[{"id":1,"password":"123456","username":"倪升武"},{"id":2,"password":"123456","username":"达人课"}],"msg":"获取用户列表成功"}

输入:localhost:8080/jsonresult/map,返回 json 如下:

{"code":"0","data":{"作者信息":{"id":1,"password":"","username":"倪升武"},"CSDN地址":null,"粉丝数量":4153,"博客地址":"http://blog.itcodai.com"},"msg":"操作成功!"}

通过封装,我们不但将数据通过 json 传给前端或者其他接口,还带上了状态码和提示信息,这在实际项目场景中应用非常广泛。

4. 总结

本节主要对 Spring Boot 中 json 数据的返回做了详细的分析,从 Spring Boot 默认的 jackson 框架到阿里巴巴的 fastJson 框架,分别对它们的配置做了相应的讲解。另外,结合实际项目情况,总结了实际项目中使用的 json 封装结构体,加入了状态码和提示信息,使得返回的 json 数据信息更加完整。

相关文章
|
人工智能 编解码
国内原汁原味的免费sd训练工具--哩布哩布AI
国内原汁原味的免费sd训练工具--哩布哩布AI
3692 0
|
容器
uniapp中制作侧边导航栏
uniapp中制作侧边导航栏
1155 0
|
JSON Java 数据格式
Spring Boot返回Json数据及数据封装
在Spring Boot中,接口间及前后端的数据传输通常使用JSON格式。通过@RestController注解,可轻松实现Controller返回JSON数据。该注解是Spring Boot新增的组合注解,结合了@Controller和@ResponseBody的功能,默认将返回值转换为JSON格式。Spring Boot底层默认采用Jackson作为JSON解析框架,并通过spring-boot-starter-json依赖集成了相关库,包括jackson-databind、jackson-datatype-jdk8等常用模块,简化了开发者对依赖的手动管理。
908 3
|
7月前
|
存储 弹性计算 人工智能
2026年阿里云服务器新手指南:配置选购、费用价格及使用全流程(图文教程)
2026年阿里云服务器新手指南:详解三大产品线、最新价格及选型攻略。轻量服务器低至38元/年,ECS经济型99元起,GPU服务器满足AI高性能需求。教你按身份、业务、带宽、存储四维度精准选配,避开隐形成本,三步完成购买,花小钱用好云服务。
|
8月前
|
JSON Java Maven
SpringBoot使用汇总
Spring Boot 是基于 Spring 的轻量级框架,旨在简化配置、快速启动项目。它通过自动配置和约定优于配置的理念,整合第三方库,实现开箱即用,极大提升了开发效率,是当前 Java 微服务开发的主流选择。
|
人工智能 Java 数据库连接
Mybatis执行流程
本文详细分析了 MyBatis 的执行流程,介绍了其核心组件如 SqlSessionFactoryBuilder、SqlSessionFactory、SqlSession 的作用与实现原理,并通过源码解析了 SQL 语句的执行过程,包括动态代理、缓存机制及数据库查询的实现,帮助读者深入理解 MyBatis 的内部工作机制。
343 0
Mybatis执行流程
|
8月前
|
Java 测试技术 Linux
生产环境发布管理
本文介绍大型团队中基于自动化部署平台(Jenkins+K8S)的多环境发布流程,涵盖DEV、TEST、PRE、PROD各环境职责及CI/CD实践,结合Git分支管理、容器化部署与Skywalking日志追踪,实现高效发布与故障排查。
生产环境发布管理
|
8月前
|
机器学习/深度学习 存储 数据采集
🔥 高频面试题汇总
本文系统梳理了大模型核心技术,涵盖Transformer架构、训练优化、推理部署及显存估算等关键主题,并结合面试场景提供回答框架与实战计算题解析,助力深入理解与高效表达。
413 0
🔥 高频面试题汇总
|
8月前
|
JSON 安全 fastjson
使用阿里巴巴 Fastjson 替代 Spring Boot 默认的 Jackson
本文介绍在 Spring Boot 项目中如何替换默认的 Jackson,集成阿里巴巴 Fastjson 作为 JSON 处理框架。内容涵盖 Fastjson 与 Jackson 的核心对比、依赖配置、自定义消息转换器、null 值统一处理及循环引用控制,并提供安全建议与最佳实践,助你高效、安全地使用 Fastjson。