jackson學習之九:springboot整合(配置文件)

歡迎訪問我的GitHub

這裡分類和匯總了欣宸的全部原創(含配套源碼)://github.com/zq2599/blog_demos

系列文章匯總

關於springboot整合jackson

  • 本文是《jackson學習》系列的第九篇,學習如何在springboot項目中使用jackson,以springboot-2.3.3版本為例,jackson是springboot的默認json處理工具,如下圖紅框所示,jackson在maven配置中被spring-boot-starter-web間接依賴,可直接使用:

在這裡插入圖片描述

  • 在springboot項目中常用的配置方式有兩種:
  1. 用properties或yml配置文件來配置,即本篇的內容;
  2. 用配置類來配置,這是下一篇文章的主題;

本篇概覽

今天實戰內容如下:

  1. 開發springboot應用,體驗springboot默認支持jackson,包括jackson註解和ObjectMapper實例的注入;
  2. application.yml中添加jackson配置,驗證是否生效;

源碼下載

  1. 如果您不想編碼,可以在GitHub下載所有源碼,地址和鏈接信息如下表所示(//github.com/zq2599/blog_demos):
名稱 鏈接 備註
項目主頁 //github.com/zq2599/blog_demos 該項目在GitHub上的主頁
git倉庫地址(https) //github.com/zq2599/blog_demos.git 該項目源碼的倉庫地址,https協議
git倉庫地址(ssh) [email protected]:zq2599/blog_demos.git 該項目源碼的倉庫地址,ssh協議
  1. 這個git項目中有多個文件夾,本章的應用在jacksondemo文件夾下,如下圖紅框所示:

在這裡插入圖片描述

  1. jacksondemo是父子結構的工程,本篇的代碼在springbootproperties子工程中,如下圖:

在這裡插入圖片描述

開始實戰

  1. 由於同屬於《jackson學習》系列文章,因此本篇的springboot工程作為jacksondemo的子工程存在,pom.xml如下,需要注意的是parent不能使用spring-boot-starter-parent,而是通過dependencyManagement節點來引入springboot依賴:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="//maven.apache.org/POM/4.0.0" xmlns:xsi="//www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="//maven.apache.org/POM/4.0.0 //maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <artifactId>jacksondemo</artifactId>
        <groupId>com.bolingcavalry</groupId>
        <version>1.0-SNAPSHOT</version>
        <relativePath>../pom.xml</relativePath>
    </parent>
    <groupId>com.bolingcavalry</groupId>
    <artifactId>springbootproperties</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>springbootproperties</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>


    <!--不用spring-boot-starter-parent作為parent時的配置-->
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>2.3.3.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <!-- swagger依賴 -->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
        </dependency>
        <!-- swagger-ui -->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>
  1. 啟動類很平常:
package com.bolingcavalry.springbootproperties;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public 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
@EnableSwagger2
public 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("程序員欣宸", "//github.com/zq2599/blog_demos", "[email protected]"))
                //版本號
                .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 +
                '}';
    }
}
  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();
    }
}

驗證(不用配置文件)

  1. 先來看看沒有配置文件時,默認的jackson配置的表現,直接在IDEA上運行SpringbootpropertiesApplication;
  2. 瀏覽器訪問//localhost:8080/swagger-ui.html ,如下圖紅框1,json_field0和json_field1都是JsonProperty注釋,出現在了swagger的model中,這證明jackson註解已經生效:

在這裡插入圖片描述

  1. 點擊上圖的紅框2,看看springboot引用返回的序列化結果,如下圖:

在這裡插入圖片描述

  1. 另外,上述紅框中的json格式,每個屬性單獨一行,像是做了格式化調整的,這是springboot做的?還是swagger展示的時候做的?用瀏覽器訪問//localhost:8080/jsonproperty/serialization ,結果如下,可見springboot返回的是未經過格式化的json

在這裡插入圖片描述

  • 接下來咱們添加jackson相關的配置信息並驗證是否生效;

添加配置文件並驗證

  1. 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
  1. 將鼠標放置下圖紅框位置,再按住Ctlr鍵,IDEA會彈出一個浮層,提示該配置對應的jackson代碼,如下圖:

在這裡插入圖片描述

  1. 在上圖中,按住Ctlr鍵,用鼠標點擊紅框位置即可打開此配置對應的jackson源碼,如下圖:

在這裡插入圖片描述
4. 重新運行springboot應用,用瀏覽器訪問://localhost:8080/jsonproperty/serialization ,結果如下圖,可見json_field0的格式變成了yyyy-MM-dd HH:mm:ss,而且json輸出也做了格式化,證明application.yml中的配置已經生效:

在這裡插入圖片描述
5. 再來試試反序列化,打開swagger頁面,操作和響應如下圖所示,注意紅框1裏面請求參數的格式:

在這裡插入圖片描述

  • 至此,在springboot中通過yml配置jackson的操作實戰就完成了,接下來的章節,咱們在配置類中用代碼來完成yml的配置;

你不孤單,欣宸原創一路相伴

  1. Java系列
  2. Spring系列
  3. Docker系列
  4. kubernetes系列
  5. 數據庫+中間件系列
  6. DevOps系列

歡迎關注公眾號:程序員欣宸

微信搜索「程序員欣宸」,我是欣宸,期待與您一同暢遊Java世界…
//github.com/zq2599/blog_demos