关于springboot整合jackson

  • 本文是《jackson学习》系列的第九篇,学习如何在springboot项目中使用jackson,以springboot-2.3.3.RELEASE版本为例,jackson是springboot的默认json处理工具,如下图红框,jackson在maven配置中被spring-boot-starter-web间接依赖,可直接使用:

springboot 整合JUNIT_springboot 整合JUNIT


  • 在springboot项目中常用的配置方式有两种:
  1. 用properties或yml配置文件来配置,即本篇的内容;
  2. 用配置类来配置,这是下一篇文章的主题;

本篇概览

今天实战内容如下:

  1. 开发springboot应用,体验springboot默认支持jackson,包括jackson注解和ObjectMapper实例的注入;
  2. 在application.yml中添加jackson配置,验证是否生效;

源码下载

如果您不想编码,可以在GitHub下载所有源码,地址和链接信息如下表所示(
https://github.com/zq2599/blog_demos):


springboot 整合JUNIT_spring_02


  • 这个git项目中有多个文件夹,本章的应用在jacksondemo文件夹下,如下图红框所示:


springboot 整合JUNIT_json_03


  • jacksondemo是父子结构的工程,本篇的代码在springbootproperties子工程中,如下图:


springboot 整合JUNIT_json_04


开始实战

  1. 由于同属于《jackson学习》系列文章,因此本篇的springboot工程作为jacksondemo的子工程存在,pom.xml如下,需要注意的是parent不能使用spring-boot-starter-parent,而是通过dependencyManagement节点来引入springboot依赖:
<?xml version="1.0" encoding="UTF-8"?>4.0.0        jacksondemo        com.bolingcavalry1.0-SNAPSHOT../pom.xmlcom.bolingcavalry    springbootproperties    0.0.1-SNAPSHOTspringbootpropertiesDemo project for Spring Boot1.8org.springframework.boot                spring-boot-dependencies                2.3.3.RELEASEpomimportorg.springframework.boot            spring-boot-starter-web        org.springframework.boot            spring-boot-starter-test            testorg.junit.vintage                    junit-vintage-engine                io.springfox            springfox-swagger2        io.springfox            springfox-swagger-ui        org.springframework.boot                spring-boot-maven-plugin
  1. 启动类很平常:
package com.bolingcavalry.springbootproperties;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplicationpublic class SpringbootpropertiesApplication {    public static void main(String[] args) {        SpringApplication.run(SpringbootpropertiesApplication.class, args);    }}
  1. 由于用到了swagger,因此要添加swagger配置:
package com.bolingcavalry.springbootproperties;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import springfox.documentation.builders.ApiInfoBuilder;import springfox.documentation.builders.PathSelectors;import springfox.documentation.builders.RequestHandlerSelectors;import springfox.documentation.service.ApiInfo;import springfox.documentation.service.Contact;import springfox.documentation.service.Tag;import springfox.documentation.spi.DocumentationType;import springfox.documentation.spring.web.plugins.Docket;import springfox.documentation.swagger2.annotations.EnableSwagger2;@Configuration@EnableSwagger2public class SwaggerConfig {    @Bean    public Docket createRestApi() {        return new Docket(DocumentationType.SWAGGER_2)                .apiInfo(apiInfo())                .tags(new Tag("JsonPropertySerializationController", "JsonProperty相关测试"))                .select()                // 当前包路径                .apis(RequestHandlerSelectors.basePackage("com.bolingcavalry.springbootproperties.controller"))                .paths(PathSelectors.any())                .build();    }    //构建 api文档的详细信息函数,注意这里的注解引用的是哪个    private ApiInfo apiInfo() {        return new ApiInfoBuilder()                //页面标题                .title("SpringBoot整合Jackson(基于配置文件)")                //创建人                .contact(new Contact("程序员欣宸", "https://github.com/zq2599/blog_demos", "zq2599@gmail.com"))                //版本号                .version("1.0")                //描述                .description("API 描述")                .build();    }}
  1. 序列化和反序列化用到的Bean类,可见使用了JsonProperty属性来设置序列化和反序列化时的json属性名,field0字段刻意没有get方法,是为了验证JsonProperty的序列化能力:
package com.bolingcavalry.springbootproperties.bean;import com.fasterxml.jackson.annotation.JsonProperty;import io.swagger.annotations.ApiModel;import io.swagger.annotations.ApiModelProperty;import java.util.Date;@ApiModel(description = "JsonProperty注解测试类")public class Test {    @ApiModelProperty(value = "私有成员变量")    @JsonProperty(value = "json_field0", index = 1)    private Date field0 = new Date();    public void setField0(Date field0) {        this.field0 = field0;    }    @ApiModelProperty(value = "来自get方法的字符串")    @JsonProperty(value = "json_field1", index = 0)    public String getField1() {        return "111";    }    @Override    public String toString() {        return "Test{" +                "field0=" + field0 +                '}';    }}1234567891011121314151617181920212223242526272829303132
  1. 测试用的Controller代码如下,很简单只有两个接口,serialization返回序列化结果,deserialization接受客户端请求参数,反序列化成实例,通过toString()来检查反序列化的结果,另外,还通过Autowired注解从spring容器中将ObjectMapper实例直接拿来用:
package com.bolingcavalry.springbootproperties.controller;import com.bolingcavalry.springbootproperties.bean.Test;import com.fasterxml.jackson.core.JsonProcessingException;import com.fasterxml.jackson.databind.ObjectMapper;import io.swagger.annotations.Api;import io.swagger.annotations.ApiOperation;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.RequestBody;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import org.springframework.web.bind.annotation.RestController;@RestController@RequestMapping("/jsonproperty")@Api(tags = {"JsonPropertySerializationController"})public class JsonPropertySerializationController {    private static final Logger logger = LoggerFactory.getLogger(JsonPropertySerializationController.class);    @Autowired    ObjectMapper mapper;    @ApiOperation(value = "测试序列化", notes = "测试序列化")    @RequestMapping(value = "/serialization", method = RequestMethod.GET)    public Test serialization() throws JsonProcessingException {        Test test = new Test();        logger.info(mapper.writeValueAsString(test));        return test;    }    @ApiOperation(value = "测试反序列化", notes="测试反序列化")    @RequestMapping(value = "/deserialization",method = RequestMethod.PUT)    public String deserialization(@RequestBody Test test) {        return test.toString();    }}

验证(不用配置文件)

  • 先来看看没有配置文件时,默认的jackson配置的表现,直接在IDEA上运行SpringbootpropertiesApplication;
  • 浏览器访问http://localhost:8080/swagger-ui.html ,如下图红框1,json_field0json_field1都是JsonProperty注释,出现在了swagger的model中,这证明jackson注解已经生效:


springboot 整合JUNIT_序列化_05


  • 点击上图的红框2,看看springboot引用返回的序列化结果,如下图:


springboot 整合JUNIT_springboot整合junit_06


  • 另外,上述红框中的json格式,每个属性单独一行,像是做了格式化调整的,这是springboot做的?还是swagger展示的时候做的?用浏览器访问http://localhost:8080/jsonproperty/serialization ,结果如下,可见springboot返回的是未经过格式化的json


springboot 整合JUNIT_springboot 整合JUNIT_07


  • 接下来咱们添加jackson相关的配置信息并验证是否生效;

添加配置文件并验证

  • 在resources目录新增application.yml文件,内容如下:
spring:  jackson:    # 日期格式化    date-format: yyyy-MM-dd HH:mm:ss    # 序列化相关    serialization:      # 格式化输出      indent_output: true      # 忽略无法转换的对象      fail_on_empty_beans: true    # 反序列化相关    deserialization:      # 解析json时,遇到不存在的属性就忽略      fail_on_unknown_properties: false    # 设置空如何序列化    defaultPropertyInclusion: NON_EMPTY    parser:      # 允许特殊和转义符      allow_unquoted_control_chars: true      # 允许单引号      allow_single_quotes: true
  • 将鼠标放置下图红框位置,再按住Ctlr键,IDEA会弹出一个浮层,提示该配置对应的jackson代码,如下图:


springboot 整合JUNIT_springboot整合junit_08


  • 在上图中,按住Ctlr键,用鼠标点击红框位置即可打开此配置对应的jackson源码,如下图:


springboot 整合JUNIT_springboot整合junit_09


  • 重新运行springboot应用,用浏览器访问:http://localhost:8080/jsonproperty/serialization ,结果如下图,可见json_field0的格式变成了yyyy-MM-dd HH:mm:ss,而且json输出也做了格式化,证明application.yml中的配置已经生效:


springboot 整合JUNIT_spring_10


  • 再来试试反序列化,打开swagger页面,操作和响应如下图所示,注意红框1里面请求参数的格式:


springboot 整合JUNIT_springboot整合junit_11


  • 至此,在springboot中通过yml配置jackson的操作实战就完成了,接下来的章节,咱们在配置类中用代码来完成yml的配置;