• 简介

    • Spring Boot 支持的 Json 库
    • Spring Web 中的序列化、反序列化
  • 指定类的 Json 序列化、反序列化
  • @JsonTest
  • Spring Boot 中的 json 配置
    • Jackson 配置
    • GSON 配置
  • Spring Boot 中使用 Fastjson
  • 示例源码
  • 引申和引用

简介

Spring Boot 支持的 Json 库

Spring Boot 支持三种 Json 库:

  • Gson
  • Jackson
  • JSON-B

Jackson 是 Spring Boot 官方推荐的默认库。

Spring Boot 提供了 Jackson 的自动配置,Jackson 是 spring-boot-starter-json 的一部分。当 Jackson 在类路径上时,会自动配置 ObjectMapper bean。

Spring Boot 提供了 Gson 的自动配置。当 Gson 在 classpath 上时,会自动配置 Gson bean。提供了几个 spring.gson.* 配置属性来自定义配置。为了获得更多控制,可以使用一个或多个 GsonBuilderCustomizer bean。

Spring Boot 提供了 JSON-B 的自动配置。当 JSON-B API 在 classpath 上时,将自动配置 Jsonb bean。首选的 JSON-B 实现是 Apache Johnzon,它提供了依赖关系管理。

Spring Web 中的序列化、反序列化

以下注解都是 spring-web 中提供的支持。

@ResponseBody

@Responsebody 注解用于将 Controller 的方法返回的对象,通过适当的 HttpMessageConverter 转换为指定格式后,写入到 HTTP Response 对象的 body 数据区。一般在异步获取数据时使用。通常是在使用 @RequestMapping 后,返回值通常解析为跳转路径,加上 @Responsebody 后返回结果不会被解析为跳转路径,而是直接写入 HTTP 响应正文中。

示例:

@ResponseBody
@RequestMapping(name = "/getInfo", method = RequestMethod.GET)
public InfoDTO getInfo() {return new InfoDTO();
}

@RequestBody

@RequestBody 注解用于读取 HTTP Request 请求的 body 部分数据,使用系统默认配置的 HttpMessageConverter 进行解析,然后把相应的数据绑定到要返回的对象上;再把 HttpMessageConverter 返回的对象数据绑定到 controller 中方法的参数上。

request 的 body 部分的数据编码格式由 header 部分的 Content-Type 指定。

示例:

@RequestMapping(name = "/postInfo", method = RequestMethod.POST)
public void postInfo(@RequestBody InfoDTO infoDTO) {// ...
}

@RestController

Spring 4 以前:

如果需要返回到指定页面,则需要用 @Controller 配合视图解析器 InternalResourceViewResolver 。

如果需要返回 JSON,XML 或自定义 mediaType 内容到页面,则需要在对应的方法上加上 @ResponseBody 注解。

Spring 4 以后,新增了 @RestController 注解:

它相当于 @Controller + @RequestBody 。

如果使用 @RestController 注解 Controller,则 Controller 中的方法无法返回 jsp 页面,或者 html,配置的视图解析器 InternalResourceViewResolver 将不起作用,直接返回内容。

指定类的 Json 序列化、反序列化

如果使用 Jackson 序列化和反序列化 JSON 数据,您可能需要编写自己的 JsonSerializer 和 JsonDeserializer 类。自定义序列化程序通常通过模块向 Jackson 注册,但 Spring Boot 提供了另一种 @JsonComponent 注释,可以更容易地直接注册 Spring Beans。

您可以直接在 JsonSerializer 或 JsonDeserializer 实现上使用 @JsonComponent 注释。您还可以在包含序列化程序/反序列化程序作为内部类的类上使用它,如以下示例所示:

import java.io.*;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.databind.*;
import org.springframework.boot.jackson.*;@JsonComponent
public class Example {public static class Serializer extends JsonSerializer<SomeObject> {// ...}public static class Deserializer extends JsonDeserializer<SomeObject> {// ...}}

ApplicationContext 中的所有 @JsonComponent bean 都会自动注册到 Jackson。因为 @JsonComponent 是使用 @Component 进行元注释的,所以通常的组件扫描规则适用。

Spring Boot 还提供了 JsonObjectSerializer 和 JsonObjectDeserializer 基类,它们在序列化对象时提供了标准 Jackson 版本的有用替代方法。有关详细信息,请参阅 Javadoc 中的 JsonObjectSerializer 和 JsonObjectDeserializer

@JsonTest

使用 @JsonTest 可以很方便的在 Spring Boot 中测试序列化、反序列化。

使用 @JsonTest 相当于使用以下自动配置:

org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration org.springframework.boot.autoconfigure.gson.GsonAutoConfiguration org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration org.springframework.boot.autoconfigure.jsonb.JsonbAutoConfiguration org.springframework.boot.test.autoconfigure.json.JsonTestersAutoConfiguration

@JsonTest 使用示例:

想试试完整示例,可以参考:源码

@JsonTest
@RunWith(SpringRunner.class)
public class SimpleJsonTest {private final Logger log = LoggerFactory.getLogger(this.getClass());@Autowiredprivate JacksonTester<InfoDTO> json;@Testpublic void testSerialize() throws Exception {SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");InfoDTO infoDTO = new InfoDTO("JSON测试应用", "1.0.0", sdf.parse("2019-01-01 12:00:00"));JsonContent<InfoDTO> jsonContent = json.write(infoDTO);log.info("json content: {}", jsonContent.getJson());// 或者使用基于JSON path的校验assertThat(jsonContent).hasJsonPathStringValue("@.appName");assertThat(jsonContent).extractingJsonPathStringValue("@.appName").isEqualTo("JSON测试应用");assertThat(jsonContent).hasJsonPathStringValue("@.version");assertThat(jsonContent).extractingJsonPathStringValue("@.version").isEqualTo("1.0.0");assertThat(jsonContent).hasJsonPathStringValue("@.date");assertThat(jsonContent).extractingJsonPathStringValue("@.date").isEqualTo("2019-01-01 12:00:00");}@Testpublic void testDeserialize() throws Exception {String content = "{\"appName\":\"JSON测试应用\",\"version\":\"1.0.0\",\"date\":\"2019-01-01\"}";InfoDTO actual = json.parseObject(content);assertThat(actual.getAppName()).isEqualTo("JSON测试应用");assertThat(actual.getVersion()).isEqualTo("1.0.0");}
}

Spring Boot 中的 json 配置

Jackson 配置

当 Spring Boot 的 json 库为 jackson 时,可以使用以下配置属性(对应 JacksonProperties 类):

spring.jackson.date-format= # Date format string or a fully-qualified date format class name. For instance, `yyyy-MM-dd HH:mm:ss`.
spring.jackson.default-property-inclusion= # Controls the inclusion of properties during serialization. Configured with one of the values in Jackson's JsonInclude.Include enumeration.
spring.jackson.deserialization.*= # Jackson on/off features that affect the way Java objects are deserialized.
spring.jackson.generator.*= # Jackson on/off features for generators.
spring.jackson.joda-date-time-format= # Joda date time format string. If not configured, "date-format" is used as a fallback if it is configured with a format string.
spring.jackson.locale= # Locale used for formatting.
spring.jackson.mapper.*= # Jackson general purpose on/off features.
spring.jackson.parser.*= # Jackson on/off features for parsers.
spring.jackson.property-naming-strategy= # One of the constants on Jackson's PropertyNamingStrategy. Can also be a fully-qualified class name of a PropertyNamingStrategy subclass.
spring.jackson.serialization.*= # Jackson on/off features that affect the way Java objects are serialized.
spring.jackson.time-zone= #  Time zone used when formatting dates. For instance, "America/Los_Angeles" or "GMT+10".
spring.jackson.visibility.*= # Jackson visibility thresholds that can be used to limit which methods (and fields) are auto-detected.

GSON 配置

当 Spring Boot 的 json 库为 gson 时,可以使用以下配置属性(对应 GsonProperties 类):

spring.gson.date-format= # Format to use when serializing Date objects.
spring.gson.disable-html-escaping= # Whether to disable the escaping of HTML characters such as '<', '>', etc.
spring.gson.disable-inner-class-serialization= # Whether to exclude inner classes during serialization.
spring.gson.enable-complex-map-key-serialization= # Whether to enable serialization of complex map keys (i.e. non-primitives).
spring.gson.exclude-fields-without-expose-annotation= # Whether to exclude all fields from consideration for serialization or deserialization that do not have the "Expose" annotation.
spring.gson.field-naming-policy= # Naming policy that should be applied to an object's field during serialization and deserialization.
spring.gson.generate-non-executable-json= # Whether to generate non executable JSON by prefixing the output with some special text.
spring.gson.lenient= # Whether to be lenient about parsing JSON that doesn't conform to RFC 4627.
spring.gson.long-serialization-policy= # Serialization policy for Long and long types.
spring.gson.pretty-printing= # Whether to output serialized JSON that fits in a page for pretty printing.
spring.gson.serialize-nulls= # Whether to serialize null fields.

Spring Boot 中使用 Fastjson

国内很多的 Java 程序员更喜欢使用阿里的 fastjson 作为 json lib。那么,如何在 Spring Boot 中将其替换默认的 jackson 库呢?

你需要做如下处理:

(1)引入 fastjson jar 包:

<dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.54</version>
</dependency>

(2)实现 WebMvcConfigurer 接口,自定义 configureMessageConverters 接口。如下所示:

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {private final Logger log = LoggerFactory.getLogger(this.getClass());/*** 自定义消息转换器* @param converters*/@Overridepublic void configureMessageConverters(List<HttpMessageConverter<?>> converters) {// 清除默认 Json 转换器converters.removeIf(converter -> converter instanceof MappingJackson2HttpMessageConverter);// 配置 FastJsonFastJsonConfig config = new FastJsonConfig();config.setSerializerFeatures(SerializerFeature.QuoteFieldNames, SerializerFeature.WriteEnumUsingToString,SerializerFeature.WriteMapNullValue, SerializerFeature.WriteDateUseDateFormat,SerializerFeature.DisableCircularReferenceDetect);// 添加 FastJsonHttpMessageConverterFastJsonHttpMessageConverter fastJsonHttpMessageConverter = new FastJsonHttpMessageConverter();fastJsonHttpMessageConverter.setFastJsonConfig(config);List<MediaType> fastMediaTypes = new ArrayList<>();fastMediaTypes.add(MediaType.APPLICATION_JSON_UTF8);fastJsonHttpMessageConverter.setSupportedMediaTypes(fastMediaTypes);converters.add(fastJsonHttpMessageConverter);// 添加 StringHttpMessageConverter,解决中文乱码问题StringHttpMessageConverter stringHttpMessageConverter = new StringHttpMessageConverter(Charset.forName("UTF-8"));converters.add(stringHttpMessageConverter);}// ...
}

SpringBoot 2.1.5(20)---JSON相关推荐

  1. SpringBoot中使用FastJson解析Json数据

    场景 1.SpringBoot默认配置的是Jackson. 2.项目搭建专栏: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/column/info/35688 ...

  2. SpringBoot将自定义对象转JSON对象问题研究

    SpringBoot JSON序列化自定义对象研究 1. 问题描述 1.1 工程代码 1.2 测试 2. 问题分析 2.1 初步分析结论 2.2 实验验证结论 2.3 问题拓展 3. 结论 摘要(干货 ...

  3. npm install WARN package.json not exists: E:\SpringBoot\workplace\D4_pc_ui\.idea\package.json

    问题描述:package.json不存在 解决:目录不正确 正确目录为:

  4. SpringBoot有关数组对象转JSON

    文章目录 前言 一.数据的插入 二.查询数据 1.插入数据 2.查询数据 总结 前言 比如,有个List<AlarmInfo>对象需要存储到mysql中,我们可以存储为varchar类型, ...

  5. SpringBoot接收前端传来的json数据

    当前端传来json数据时,后端有多种方式接收 前端json数据: {id:121, //数字name:"lhj", //字符串scoreList:[ //对象{Java:95}, ...

  6. JS高程 Chp.20 JSON 思维导图

  7. SpringBoot解析Excel文件返回JSON

    拿来就能用的解析Excel说明 一.导包 <dependency><groupId>org.apache.poi</groupId><artifactId&g ...

  8. JSON文件报错解决方法(Expected value at 1:0/Expected 'a' at 8:20)

    在构建java项目时,可能会出现.json文件报错(出现红叉叉),无论怎么调整,而且项目还能正常运行,但是这个红叉叉就是会一直存在,作为具有强迫症的我是不能忍的,下面步骤为错误描述与决解操作. jso ...

  9. java json转换

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

最新文章

  1. 【Python】 文件目录比较工具filecmp和difflib
  2. AEAI WM v1.6.0 升级说明,开源工作管理系统
  3. 大专学java还是python_零基础应该选择学习 java、php、前端 还是 python?
  4. android拍照自动裁剪_新功能上线!智能人像抠图、图片自由裁剪,PPT 还能这么玩?...
  5. 经典C语言程序100例之七六
  6. 在js中if条件为null/undefined/0/NaN/表达式时,统统被解释为false,此外均为true
  7. Qt+ArcGIS Engine 10.1 开发(一)
  8. 依赖注入与对象间关系
  9. error: ‘avcodec_alloc_frame’ was not declared in this scope
  10. CSS调试技巧:a.class 与 a .class的区别,千万不能小看空格
  11. Linux Ext2/Ext3/Ext4文件系统
  12. python内置高级数据结构
  13. 微软商店打开失败 - 错误代码 - 0x80131500
  14. 关于AMS1117-ADJ 电压调节计算
  15. Android 集成facebook 登录和分享
  16. vue 竖向纵向仿表格 动态渲染表头表格 根据id填充单元格
  17. 计算机如何计算指数函数
  18. 陕西国防 c语言第三章实训三答案,C语言程序设计实验指导
  19. 自制APP连接OneNET---实现数据监控和下发控制(HTTP)
  20. 视频教程-商超收银软件中的扫码识别商品编程解析-其他

热门文章

  1. 通过AT指令控制ESP8266
  2. J-Link cmd的使用
  3. php pear mail 发送邮件,PHP用pear自带的mail类库发邮件
  4. 用c++自制词法分析器_编译原理笔记 02 词法分析
  5. Keil(MDK-ARM-STM32)系列教程(六)Configuration(Ⅱ)
  6. 快速修改数组的某个值_我用Python,3分钟快速实现,9种经典排序算法的可视化...
  7. 单片机RAM和ROM
  8. httpd svn 编译安装_linux下php7安装与Apache配置
  9. html自动播放auto,为移动而生的 HTML 属性autocapitalize和autocorrect
  10. 【LeetCode】剑指 Offer 43. 1~n 整数中 1 出现的次数