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());
    }
}

猜你喜欢

转载自www.cnblogs.com/hankuikui/p/11429996.html
今日推荐