SpringBoot版本:2.1.18.RELEASE
,fastjson版本:1.2.58
1.声明
当前内容主要为本人学习和使用fastjson替换原生的SpringBoot中的jackson,来响应json数据
- 默认SpringBoot中采用:
MappingJackson2HttpMessageConverter这个类处理消息转换
,输出json数据 - 使用fastjson来替换上面这个转换器
- 实现标准:
按照SpringBoot官方的说法,自动将HttpMessageConverter的bean注册到HttpMessageConverters中
,所以直接创建Bean即可(配置类中)
当前fastjson版本和SpringBoot版本
<dependency>
<!-- Import dependency management from Spring Boot -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.1.18.RELEASE</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.58</version>
</dependency>
其中Controller层使用@RestController即可,返回数据类型为Object
2.错误的方式
/**
* @author admin
* @createTime 2021-02-26 13:59:23
* @description 默认配置当前的fastjson替换当前的jackson作为json转换服务
*/
@Configuration
public class JsonConfig {
@Bean
public HttpMessageConverter converter() {
FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter();
FastJsonConfig fastJsonConfig = new FastJsonConfig();
fastJsonConfig.setCharset(Charset.forName("utf-8"));
fastJsonConfig.setDateFormat("yyyy-MM-dd HH:mm:ss");
converter.setFastJsonConfig(fastJsonConfig);
converter.setSupportedMediaTypes(Arrays.asList(MediaType.ALL));
System.out.println("............");
return converter;
}
测试发现:
发现输出的content-type完全不是application/json,所以出现了错误,由于这个是通过查看继承树发现的
由于发现实际上有一个AbstractHttpMessageConverter这个(fastjson本身可以转换Object为json字符串,所以这里只是一个content-type问题),通过继承这个类来实现写出功能
3. 正确的方式
1.通过重写其中的方法,并使用FastJson来实现,即可
/**
* @author admin
* @createTime 2021-02-26 13:59:23
* @description 默认配置当前的fastjson替换当前的jackson作为json转换服务
*/
@Configuration
public class JsonConfig {
public static class MyFastJsonHttpMessageConverter extends AbstractHttpMessageConverter<Object> {
FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter();
public MyFastJsonHttpMessageConverter() {
// TODO Auto-generated constructor stub
FastJsonConfig fastJsonConfig = new FastJsonConfig();
fastJsonConfig.setCharset(Charset.forName("utf-8"));
fastJsonConfig.setDateFormat("yyyy-MM-dd HH:mm:ss");
converter.setFastJsonConfig(fastJsonConfig);
}
@Override
protected boolean supports(Class<?> clazz) {
// TODO Auto-generated method stub
System.out.println("MyFastJsonHttpMessageConverter supports method invoke");
return true;
}
@Override
protected void writeInternal(Object t, HttpOutputMessage outputMessage)
throws IOException, HttpMessageNotWritableException {
// String json = JSON.toJSONString(t);
converter.write(t, MediaType.APPLICATION_JSON_UTF8, outputMessage);
System.out.println("fastjson convert obj to String");
/*
* OutputStream outputStream = outputMessage.getBody();
* outputStream.write(json.getBytes(Charset.forName("utf-8")));
*/
}
// 这个是处理前台传递到后台,读取的数据类型
/*
* @Override protected boolean canRead(MediaType mediaType) { // TODO
* Auto-generated method stub if(mediaType==MediaType.APPLICATION_JSON ||
* mediaType==MediaType.APPLICATION_JSON_UTF8) { return true; } return false; }
*/ // 由于这里只处理,后台向前台的转换器,所以这里不需要
// 这个是必须的,否则无法正常使用该转换器,这里实际的mediaType返回null
@Override
protected boolean canWrite(MediaType mediaType) {
// TODO Auto-generated method stub
return true;
}
@Override
protected Object readInternal(Class<? extends Object> clazz, HttpInputMessage inputMessage)
throws IOException, HttpMessageNotReadableException {
if (clazz == null) {
return null;
}
Object read = converter.read(clazz, inputMessage);
return read;
}
}
@Bean
public HttpMessageConverter converter() {
MyFastJsonHttpMessageConverter converter = new MyFastJsonHttpMessageConverter();
/*
* FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter();
* FastJsonConfig fastJsonConfig = new FastJsonConfig();
* fastJsonConfig.setCharset(Charset.forName("utf-8"));
* fastJsonConfig.setDateFormat("yyyy-MM-dd HH:mm:ss");
* converter.setFastJsonConfig(fastJsonConfig);
* converter.setSupportedMediaTypes(Arrays.asList(MediaType.ALL));
* System.out.println("............");
*/
return converter;
}
}
此时测试得到:
此时的结果是正常的,注意canWrite方法和supports必须重写,并且返回一定为true,否则该消息转换器不生效,canRead表示前台向后台传递的数据
,可以自己处理写还是不写!
4.总结
1.在使用替换的时候,FastJsonHttpMessageConverter 输出的是text/html类型不是application/json类型
2.如果使用继承方式AbstractHttpMessageConverter的时候,一定要小心当前的supports和canWrite方法
3.canWrite方法中传递的为null类型
,一旦配置失败就还是会用jackson的来处理!