admin管理员组文章数量:1538122
笔者日常:说实话,这篇博客,过程有点曲折;我想搞明白为什么众多特性不兼容,自己跟了源码、看
了动态生成的class文件,可能水平不够,我找了很久还是没找到原因,于是请教了一位大神,
那么久过去了,一点回信也没有,哎~起码的尊重呢,可能太忙了吧。
SpringBoot使用fastjson作为消息转换器的步骤:
第一步:引入fastjson依赖。
<!-- https://mvnrepository/artifact/com.alibaba/fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.54</version>
</dependency>
第二步:配置消息转换器。
上图只是最基本最简单的配置;在实际使用时,我们还可能根据自己的需求的不同,配置一些相关特性(如:防止中文乱码、字符串为null时输出””而非null,list为null时输出[]而非null,数值字段如果为null,输出为0而非null,Boolean默认输出false等等)。这里给出一个示例:
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
/**
* 自定义部分MVC配置
*
* @author JustryDeng
* @date 2019/8/14 13:06
*/
@Component
public class MyWebMvcConfigurationSupport extends WebMvcConfigurationSupport {
/**
* 使用fastjson作为JSON消息转换器
* 使用StringHttpMessageConverter作为String消息转换器
* <p>
* 注: 一般来讲,这两个消息消息转换器就是用于绝大部分情况了;
* 如果业务环境情况等比较特殊,需要其他的消息转换器,
* 那么再追加新的转换器即可
* <p>
* 注:JSON消息转换器需要引入fastjson依赖
* StringHttpMessageConverter消息转换器需要引入springframework依赖
*
* @date 2019/8/14 13:06
*/
@Override
protected void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
/// -> JSON消息转换器(采用阿里的fastjson)
// 创建一个转换器对象;
FastJsonHttpMessageConverter fastJsonHttpMessageConverter = new FastJsonHttpMessageConverter();
// 个性化配置转换特性
FastJsonConfig fastJsonConfig = new FastJsonConfig();
// 配置:要格式化返回的json数据
fastJsonConfig.setSerializerFeatures(SerializerFeature.PrettyFormat);
// 配置:把空的值的key也返回
fastJsonConfig.setSerializerFeatures(SerializerFeature.WriteMapNullValue);
// 字段如果为null,输出为false,而非null
fastJsonConfig.setSerializerFeatures(SerializerFeature.WriteNullBooleanAsFalse);
// 数值字段如果为null,输出为0,而非null
fastJsonConfig.setSerializerFeatures(SerializerFeature.WriteNullNumberAsZero);
// List字段如果为null,输出为[],而非null;
fastJsonConfig.setSerializerFeatures(SerializerFeature.WriteNullListAsEmpty);
// 字符类型字段如果为null,输出为"",而非null
fastJsonConfig.setSerializerFeatures(SerializerFeature.WriteNullStringAsEmpty);
fastJsonHttpMessageConverter.setFastJsonConfig(fastJsonConfig);
// 处理中文乱码问题
List<MediaType> fastMediaTypes = new ArrayList<>(4);
fastMediaTypes.add(MediaType.APPLICATION_JSON_UTF8);
fastJsonHttpMessageConverter.setSupportedMediaTypes(fastMediaTypes);
/// -> String消息转换器
StringHttpMessageConverter stringConverter = new StringHttpMessageConverter();
stringConverter.setDefaultCharset(Charset.forName("UTF-8"));
stringConverter.setSupportedMediaTypes(fastMediaTypes);
// 将convert添加到converters当中.
converters.add(fastJsonHttpMessageConverter);
converters.add(stringConverter);
super.configureMessageConverters(converters);
}
}
fastjson对日期类型的处理:
声明:对Date类型字段的处理方式较多,这里只给出三种比较常用的方式。
方式一:配置了fastjson作为消息转换器后,在模型的对应日期字段上面使用@JSONField(format = "...")来指定格式。
方式二:在配置fastjson作为消息转换器的使用,通过.setDateFormat("...")指定全局Date字段的序列化格式。
注:如果使用了.setDateFormat("...")的话,那么模型字段上通过 @JSONField(format = "...")指定日期序列化格式的方
式,将不起作用。
方式三:在配置fastjson作为消息转换器的时候,使用.setSerializerFeatures(SerializerFeature.WriteDateUseDateFormat)
指定全局Date字段的默认序列化格式。
注意事项:
当上述三种方式或其中两种方式并存时,会采用优先级高的方式。三种方式的优先级:方式二 > 方式一 > 方式三, 即:
在fastjson消息转换器里配置.setDateFormat("...")
>
在字段模型上添加 @JSONField(format = "...")
>
在fastjson消息转换器里配置.setSerializerFeatures(SerializerFeature.WriteDateUseDateFormat);
自定义序列化器(反序列化器):
声明:fastjson的特性SerializerFeature有很多,但并不是每一种特性都一定和其它相互兼容的,这就可能造成:在
消息转换器中配置的众多特性,部分生效了,部分没生效;这时我们可以考虑使用自定义的序列化器来解决
这个问题;下面就简单演示自定义序列化器,并作出使用演示。
自定义序列化器、反序列化器:
import com.alibaba.fastjson.parser.DefaultJSONParser;
import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer;
import com.alibaba.fastjson.serializer.JSONSerializer;
import com.alibaba.fastjson.serializer.ObjectSerializer;
import com.alibaba.fastjson.serializer.SerializeWriter;
import java.lang.reflect.Type;
/**
* 自定义序列化器、反序列化器
*
* @author JustryDeng
* @date 2019/8/13 18:40
*/
public class MyDateSerializerAndDeserializer implements ObjectSerializer, ObjectDeserializer {
/**
* 序列化
*
* 程序给前端响应时, 就会将数据序列化为二进制流,进行传输
*/
@Override
public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) {
SerializeWriter out = serializer.getWriter();
if (fieldType == java.util.Date.class) {
out.write("\"我是java.util.Date.class\"");
return;
} else if (fieldType == java.sql.Date.class) {
out.write("\"我是java.sql.Date.class\"");
return;
}
out.write(String.valueOf(object));
}
/**
* 反序列化
* 注:本文主要演示序列化, 反序列化这里就不作任何修改了
*
* 程序从前端获取请求的数据时, 就会将二进制流反序列化为数据类型T
*/
@Override
public <T> T deserialze(DefaultJSONParser parser, Type type, Object fieldName) {
// do something
return null;
}
@Override
public int getFastMatchToken() {
return 0;
}
}
在fastjson消息转换器中配置使用自定义的序列化器:
注:也可以(不在消息转换器里面统一指定序列化器、反序列化器,而)直接在字段上指定该字段使用哪个序列化器,如:
测试一下:
相关Person类:
注:其中用到了lombok注解(这并不是必须的)。
相关DemoController类:
启动项目,访问http://localhost:8080/abc:
由此可见,自定义序列化器成功!
再次提示:fastjson的特性SerializerFeature有很多,但并不是每一种特性都一定和其它相互兼容的,这就可能造成:在
消息转换器中配置的众多特性,部分生效了,部分没生效;这时我们可以考虑使用自定义的序列化器来解决
这个问题。
^_^ 如有不当之处,欢迎指正
^_^ 本文已经被收录进《程序员成长笔记(六)》,笔者JustryDeng
版权声明:本文标题:SpringBoot使用fastjosn作为消息转换器、fastjosn对日期的处理、自定义序列化器解决SerializerFeature兼容问题 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://m.elefans.com/dianzi/1726967866a1092425.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论