spring boot 枚举使用的坑2
上一篇说到在枚举当在controller的方法做参数时的坑,解决方法是配置了一个converter,后来想想,如果不闲每次都加一个注解麻烦的话,可以在参数前面加一个注解,添加一个解析器应该也可以解决这个问题。
现在来说说枚举的第二个坑,前提条件和上一篇的一样:就是这个枚举:
@Getter @AllArgsConstructor public enum EnumExpenseType implements BaseEnum { 小欢喜(1), 大欢喜(2); private final int value; }
现在还是把它当参数,但是是做为一个复杂对象的属性来传,这个复杂对象是通过jackjson反序列化得到的。
就是前端传过来一个json串,我们在controller中把它反序列化对象。
就不演示了,直接说结论了,jackson默认是使用索引值ordinal来做映射的,所以还是不能满足我们的需求。
所以不是修改jackson的配置,或对每个枚举做修改,添加一个@JsonCreator,我还是喜欢统一的配置,
直接上代码:
/** * 解决BaseEnum接收前端json时,应按照value值进行处理,实际是按照索引值处理 */ @JsonComponent public class BaseEnumDeserializer extends JsonDeserializer<BaseEnum> { @Override public BaseEnum deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { JsonNode node = jp.getCodec().readTree(jp); String currentName = jp.currentName(); Object currentValue = jp.getCurrentValue(); Class findPropertyType = BeanUtils.findPropertyType(currentName, currentValue.getClass()); BaseEnum b = EnumUtil.getEnumByValue(findPropertyType, node.intValue()); return b; } }
/** * @author :hkk */ public class AuditHttpMessageConverter extends MappingJackson2HttpMessageConverter { public AuditHttpMessageConverter(ObjectMapper objectMapper) { SimpleModule simpleModule1 = new SimpleModule(); simpleModule1.addDeserializer(BaseEnum.class, new BaseEnumDeserializer()); objectMapper.registerModule(simpleModule1); super.setObjectMapper(objectMapper); } }
再配置一个webmvcconfig:
@Override public void extendMessageConverters(List<HttpMessageConverter<?>> converters) { //替换自带json序列化器 MappingJackson2HttpMessageConverter converter; Iterator<HttpMessageConverter<?>> it = converters.iterator(); while (it.hasNext()) { if (ClassUtils.isAssignable(it.next().getClass(), MappingJackson2HttpMessageConverter.class)) { it.remove(); } } converters.add(new MappingJackson2HttpMessageConverter(objectMapper));//BaseEnum反序列化支持 converters.add(new AuditHttpMessageConverter(builder.build())); }
配置完成。
这是反序列化,那序列化还是有问题,可以在value上打个注解@jsonValue,但如果闲麻烦的话,可以做一个统一的配置, 直接上代码:
/** * BaseEnum及子类,序列化成json时,指定序列值为getvalue*/ @JsonComponent public class BaseEnumSerializer extends JsonSerializer<BaseEnum> { @Override public void serialize(BaseEnum value, JsonGenerator gen, SerializerProvider serializers) throws IOException { gen.writeNumber(value.getValue()); } }