002 Spring Boot 返回 JSON

上一遍 中我们实践了如何创建了一个 Spring Boot 项目,并实现了一个简易的 Hello Spring Boot 输出,但是在我们实际开发过程中,尤其是当前前后端分离的开发模式,后端输出的数据大部分都是 api 接口形式,而且大多也都是 json 数据格式,所以这篇,我们来实践下如何使用 Spring Boot 输出 JSON 数据。

默认 Jackson

我们先根据 上遍 创建一个 Spring Boot 项目,然后在创建 controller ,之后目录结构:

├─javaapp
|    ├─pom.xml
|    ├─src
|    |  ├─main
|    |  |  ├─java
|    |  |  |  ├─com
|    |  |  |  |  ├─jdz
|    |  |  |  |  |  ├─App.java
|    |  |  |  |  |  ├─controllers
|    |  |  |  |  |  |      └UserController.java

UserController.java 内容:

package com.jdz.controllers;

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

@RestController
public class UserController {

}

上一遍 中的 controller 不一样的是,此时我们用的是 @RestController 注解

创建 bean

为了返回 JSON 格式数据,这里我们再创建一个 User 类对象。
我们在项目中创建 beans 包,在该包下创建 User 类:

package com.jdz.beans;

import java.io.Serializable;
import java.util.Date;

public class User implements Serializable {
    private Integer uid;
    private String name;
    @JsonFormat(pattern = "yyy-mm-dd HH:mm:ss")
    private Date birthday;
    @JsonIgnore
    private String addr;

    // 省去 构造函数、set方法、get方法
}

@JsonFormat:
@JsonIgnore: 在转成 json 时忽略该字段,即不把该字段输出

修改 UserController.java

在 UserController 类中增加 info 方法

    @RequestMapping("/info")
    public User info() {
        User user = new User(1, "张三", new Date(), "中国江西");
        return user;
    }

上一遍 相比,此时 info() 方法,可以省去 @ResponseBody (被包含在 @RestController 中)

重启服务,访问连接: http://localhost:8080/info ,无误的话,返回:

{
    uid: 1,
    name: "张三",
    birthday: "2022-24-08 10:24:40"
}

我们看到输出的内容我 json 数据,而且通过查看 http 响应的头,我们也能看到的返回的数据体格式为 json:

Content-Type: application/json

之所以我们再未进行任何的配置情况下,就能输出 json 数据,是因为 spring-boot-starter-web 依赖默认是加入了 jackson-databind 作为 json 处理器,所以我们在定义接口的时候,返回类型直接写成对象类型,spring boot 就会帮我们转换成 json 格式。

类似的其他 JSON 数据类型,也是同样的返回,如 Array, Object 等,这里就不多赘述,这部分的代码在后面的源码当中。

Spring Boot 输出 JSON 有很多方式,如上面的默认方式(jackson)、使用 Gson,或者 fastjson,或者其他的 json 处理器,这里我们重点说下 fastjson 处理器。

fastjson

fastjson是阿里巴巴的一个开源JSON解析框架,是目前JSON解析速度最快的开源框架。

1. 去除 jackson-databind 依赖

由于 spring boot 默认包含 jackson-databind 依赖,所以我们先将其移除:

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
      <exclusions>
        <exclusion>
          <groupId>com.fasterxml.jackson.core</groupId>
          <artifactId>jackson-databind</artifactId>
        </exclusion>
      </exclusions>
    </dependency>

2. 增加 fastjson 依赖

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

3. 增加配置

fastjson 启动需要相应的配置,配置的可通过两种方式:
方式一:在启动类中配置 (此方式省略)

方式二:通过 @Bean 方式注入
在项目中新增 conf 包,在 conf 包内新建 MyFastJsonConfig.java

package com.jdz.conf;

import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;

import java.util.ArrayList;
import java.util.List;

@Configuration
public class MyFastJsonConfig {

    @Bean
    public HttpMessageConverters fastjsonHttpMessageConverters() {
        // 1.定义一个converters转换消息的对象
        FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter();
        // 2.添加fastjson的配置信息,比如: 是否需要格式化返回的json数据
        FastJsonConfig fastJsonConfig = new FastJsonConfig();
        fastJsonConfig.setSerializerFeatures(SerializerFeature.PrettyFormat);
        // 3.在converter中添加配置信息
        fastConverter.setFastJsonConfig(fastJsonConfig);
        //处理中文乱码问题
        List<MediaType> oFastMediaTypeList = new ArrayList<>();
        oFastMediaTypeList.add(MediaType.APPLICATION_JSON_UTF8);
        fastConverter.setSupportedMediaTypes(oFastMediaTypeList);
        // 4.将converter赋值给HttpMessageConverter
        HttpMessageConverter<?> converter = fastConverter;
        // 5.返回HttpMessageConverters对象
        return new HttpMessageConverters(converter);
    }
}

到此,我们就可以正常使用 fastjson 输出数据啦。

另外,我们在 User.java 里使用到了 Date 类型,如果不做任何处理的话,会输出时间戳,我们之前是有对其进行格式化的,输出 yyy-mm-dd HH:mm:ss 格式,使用的是:

    @JsonFormat(pattern = "yyy-mm-dd HH:mm:ss")
    private Date birthday;

如果要在 fastjson 依然使用此格式,需要使用:

@JSONField(format = "yyy-mm-dd HH:mm:ss")
private Date birthday;

源码: https://github.com/xiongxianhe/springboot.git

发表评论