1. 前言

fastjson 是阿里巴巴的开源 JSON 解析库,它可以解析 JSON 格式的字符串,支持将 Java Bean 序列化为JSON字符串,也可以从 JSON字符串反序列化到 JavaBean。
还有如 Jackson 、Gson 等等 JSON 解析库也很强大。
2. 对 Enum 的特殊处理
2.1 前戏
在我们开发中常常会用到枚举,比如表示会员等级、性别、是否激活等等,本来拿性别来举例,0为女,1为男。
先介绍一下枚举的一个特性 ordinal ,它是一个常量

它记录这枚举常量的序数,从0开始,像数组索引一样,我们可以合理地利用这个特性(虽然很多地方说不推荐用,但是个人觉得是可以合理利用的)
定义一个Sex枚举
| 12
 3
 4
 
 | public enum Sex {female,
 male,
 }
 
 | 
那么意味着 female 为0,male 为1 ,这个时候不管前台传值0或者值 female ,我们都知道能解析到 female 这个常量

为0时也能解析到,这里就不演示了。我们可以发现返回的 sex 也是 female ,那如何返回0呢,这个时候我们就需要自定义枚举序列化规则了
2.2 定制序列化规则
| 12
 3
 4
 5
 6
 7
 
 | public class SexEnumSerializer implements ObjectSerializer {@Override
 public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException {
 Sex sex = (Sex) object;
 serializer.out.writeInt(sex.ordinal());
 }
 }
 
 | 
实现 fasjson 的 ObjectSerializer 去自定义 Sex 这个枚举的序列化规则,然后在类的属性上使用



当响应时可以看到经过了我们自定义的序列化规则,在这里我们可以获取到响应 json 以及字段名、类型等等信息,我们在这个时候做点手脚就可以返回 ordinal 了
2.3 定制反序列化规则
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 
 | public class SexEnumDeSerializer implements ObjectDeserializer {
 @Override
 public <T> T deserialze(DefaultJSONParser parser, Type type, Object fieldName) {
 Object parse = parser.parse();
 if (Objects.isNull(parse)){
 return (T) Sex.female;
 }
 return (T) parse;
 }
 
 @Override
 public int getFastMatchToken() {
 return 0;
 }
 }
 
 | 
为我们的 Sex 配置反序列化规则


此时 sex 为 null ,在我们反序列化时就会按照我们的规则选择 female ,然后返回时序列化 为 ordianl ,也就是0
3. 配置 HttpMessageConverter
可能有的小伙伴进行上面操作时,达不到预期效果,因为 SpringBoot 默认 JSON 解析库是 Jackson !!(接口为什么返回的是 JSON 这是基础,这里不过多阐述),我们需要去定制 HttpMessageConverter,我们的请求响应文本都是它处理的,既然默认是 Jackson ,那么我们就改成 Fastjson 不就行了 ,直接上代码
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 
 | package cn.this52.fastjsondemo;
 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.web.servlet.config.annotation.WebMvcConfigurer;
 
 import java.nio.charset.StandardCharsets;
 
 @Configuration
 public class BaseWebMvcConfig implements WebMvcConfigurer {
 
 
 
 
 @Bean
 public HttpMessageConverters fastJsonHttpMessageConverter() {
 
 FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter();
 
 
 FastJsonConfig fastJsonConfig = new FastJsonConfig();
 
 SerializerFeature[] serializerFeatures = new SerializerFeature[]{
 
 
 
 
 
 SerializerFeature.WriteMapNullValue,
 
 SerializerFeature.WriteEnumUsingToString,
 
 
 
 
 
 SerializerFeature.WriteNullListAsEmpty,
 
 SerializerFeature.WriteNullStringAsEmpty,
 
 SerializerFeature.WriteNullNumberAsZero,
 
 SerializerFeature.WriteNullBooleanAsFalse,
 
 
 
 
 
 
 
 
 
 SerializerFeature.WriteBigDecimalAsPlain,
 
 SerializerFeature.WriteDateUseDateFormat,
 
 SerializerFeature.DisableCircularReferenceDetect,
 
 SerializerFeature.PrettyFormat,
 };
 
 fastJsonConfig.setSerializerFeatures(serializerFeatures);
 
 fastJsonConfig.setCharset(StandardCharsets.UTF_8);
 
 fastJsonConfig.setDateFormat("yyyy-MM-dd HH:mm:ss");
 
 
 fastConverter.setFastJsonConfig(fastJsonConfig);
 
 
 return new HttpMessageConverters(fastConverter);
 }
 }
 
 | 
具体特性可以去看看文档或者源码
4. 最后
需要注意的是在一个对象中对多个属性使用相同的规则,只会选择第一个。
很多问题都是在实际开发中遇到的问题,需要我们去解决,也就衍生出了各种方案,但我们要知道的是自定义一时爽,维护火葬场,还是得根据具体需要去选择方案吧。
上面的例子很简单,不仅限是枚举,其他任意对象都是可以操作的,可以有更复杂的处理,举一反三有无限种可能!