导读
这是一系列关于 SpringBoot Web框架实战 的教程,从项目的创建,到一个完整的 web 框架(包括异常处理、拦截器、context 上下文等);从0开始,到一个可以直接运用在生产环境中的web框架。而且所有源码均开源。
在 上一遍 中我们实践了如何创建了一个 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 内容:
java
package com.jdz.controllers;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class UserController {
}
和 上一遍 中的 controller 不一样的是,此时我们用的是 @RestController
注解
创建 bean
为了返回 JSON 格式数据,这里我们再创建一个 User 类对象。
我们在项目中创建 beans 包,在该包下创建 User 类:
java
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 方法
java
@RequestMapping("/info")
public User info() {
User user = new User(1, "张三", new Date(), "中国江西");
return user;
}
与 上一遍 相比,此时 info()
方法,可以省去 @ResponseBody
(被包含在 @RestController
中)
重启服务,访问连接: http://localhost:8080/info ,无误的话,返回:
json
{
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 依赖,所以我们先将其移除:
xml
<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 依赖
xml
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>2.0.9</version>
</dependency>
3. 增加配置
fastjson 启动需要相应的配置,配置的可通过两种方式:
方式一:在启动类中配置 (此方式省略)
方式二:通过 @Bean 方式注入
在项目中新增 conf 包,在 conf 包内新建 MyFastJsonConfig.java
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 格式,使用的是:
java
@JsonFormat(pattern = "yyy-mm-dd HH:mm:ss")
private Date birthday;
如果要在 fastjson 依然使用此格式,需要使用:
java
@JSONField(format = "yyy-mm-dd HH:mm:ss")
private Date birthday;