SpringBoot之替换jackson为fastjson来输出对象到前台

SpringBoot版本:2.1.18.RELEASE,fastjson版本:1.2.58

1.声明

当前内容主要为本人学习和使用fastjson替换原生的SpringBoot中的jackson,来响应json数据

  1. 默认SpringBoot中采用:MappingJackson2HttpMessageConverter这个类处理消息转换,输出json数据
  2. 使用fastjson来替换上面这个转换器
  3. 实现标准:按照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的来处理!

猜你喜欢

转载自blog.csdn.net/weixin_45492007/article/details/114130496