目录
一、引入依赖
二、配置方式
三、测试
这篇文章使用到的是springboot2.7.0 + fastjson2.0.6
一、引入依赖
springboot默认使用jackson作为json解析器,所以需要剔除这部分的依赖。
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.0</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>org.liurb</groupId>
<artifactId>springboot-fastjson</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springboot-fastjson</name>
<description>springboot-fastjson</description>
<properties>
<java.version>1.8</java.version>
<fastjson.version>2.0.6</fastjson.version>
<lombok.version>1.18.24</lombok.version>
<hutool.version>5.8.3</hutool.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<!-- 剔除jackson -->
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-json</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>${fastjson.version}</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>${hutool.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
没剔除jackson时,可以看到引入的依赖中包括了好几个jackson的jar包。
剔除后,这部分的依赖就没有了,并可以看到fastjson的依赖也引进来了。
二、配置方式
集成WebMvcConfigurationSupport,并重写configureMessageConverters方法,加入fastjson的配置规则。
@Configuration
public class BackendWebMvcConfig extends WebMvcConfigurationSupport {
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
//定义一个convert转换消息的对象
FastJsonHttpMessageConverter fastConverter=new FastJsonHttpMessageConverter();
//添加fastjson的配置信息,比如是否要格式化返回的json数据;
FastJsonConfig fastJsonConfig = new FastJsonConfig();
fastJsonConfig.setWriterFeatures(
//是否输出值为null的字段,默认为false
JSONWriter.Feature.WriteMapNullValue,
//将Collection类型字段的字段空值输出为[]
JSONWriter.Feature.WriteNullListAsEmpty,
//将字符串类型字段的空值输出为空字符串
JSONWriter.Feature.WriteNullStringAsEmpty
);
//在convert中添加配置信息
fastConverter.setFastJsonConfig(fastJsonConfig);
//设置支持的媒体类型
fastConverter.setSupportedMediaTypes(Collections.singletonList(MediaType.APPLICATION_JSON));
//设置默认字符集
fastConverter.setDefaultCharset(StandardCharsets.UTF_8);
//将convert添加到converters
converters.add(0, fastConverter);
//解决返回字符串带双引号问题
StringHttpMessageConverter stringHttpMessageConverter = new StringHttpMessageConverter();
stringHttpMessageConverter.setSupportedMediaTypes(Collections.singletonList(MediaType.TEXT_PLAIN));
stringHttpMessageConverter.setDefaultCharset(StandardCharsets.UTF_8);
converters.add(0, stringHttpMessageConverter);
super.addDefaultHttpMessageConverters(converters);
}
/**
* 添加静态资源
*
* @param registry
*/
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/**")
.addResourceLocations("classpath:/static/")
.addResourceLocations("classpath:/templates/")
.addResourceLocations("classpath:/META-INF/resources/");
}
/**
* 跨域支持
*
* @param registry
*/
@Override
public void addCorsMappings(CorsRegistry registry) {
//对哪些目录可以跨域访问
registry.addMapping("/**")
//允许哪些网站可以跨域访问
.allowedOrigins("*")
//允许哪些方法
.allowedMethods("GET", "POST", "DELETE", "PUT", "PATCH", "OPTIONS", "HEAD")
.maxAge(3600 * 24);
}
}
相对于fastjson的1.x版本,对SerializerFeature属性进行了调整,v1.x版本的写法如下。
同时,这边还处理输出字符串会带上双引号的问题。使用StringHttpMessageConverter,并将其添加到消息解析器队列的第一位。
StringHttpMessageConverter stringHttpMessageConverter = new StringHttpMessageConverter();
stringHttpMessageConverter.setSupportedMediaTypes(Collections.singletonList(MediaType.TEXT_PLAIN));
stringHttpMessageConverter.setDefaultCharset(StandardCharsets.UTF_8);
converters.add(0, stringHttpMessageConverter);
三、测试
我们通过fastjson的注解,看看是否配置生效。
定义一个测试的控制器,以post的方式,传递json格式,我们用一个dto类来封装这部分的参数。
@RequestMapping("/api/fastjson")
@RestController
public class FastjsonDemoController {
@PostMapping("/request")
public FastjsonDemoResponse demo(@RequestBody FastjsonDemoRequest fastjsonDemoRequest) {
FastjsonDemoResponse response = new FastjsonDemoResponse();
response.setUserName(fastjsonDemoRequest.getUserName());
response.setAge(fastjsonDemoRequest.getAge());
return response;
}
}
dto请求参数部分代码
@Data
public class FastjsonDemoRequest {
@JSONField(name = "user_name")
private String userName;
@JSONField(name = "age")
private Integer age;
}
dto响应参数部分代码
@Data
public class FastjsonDemoResponse {
@JSONField(name = "user_name")
private String userName;
@JSONField(name = "age")
private Integer age;
@JSONField(name = "today_timestamp")
private LocalDateTime localDateTime;
}
可以看到这边使用了JSONField注解,它可以对参数进行命名处理,不仅可以定义输入key的名称,同时也可以定义输出的名称。
我们通过postman来测试一下效果。
可以看到我们传入的用户名是以下划线表示,而我们定义的dto是驼峰形式。
从调试窗口可以看到,userName字段是有值的,这就说明我们配置的fastjson已经生效。
接下来我们看看返回响应的结果。
响应的用户名,也是下划线形式的,说明序列化时fastjson配置也同样生效。
至此,一个简单的消息解析器就配置完毕。