• 基于jackson 注解 入参 枚举 反序列化 实操


    浪费俩小时写了这个,不多说 直接上代码。


    1. 注解
    @Documented
    @JacksonAnnotationsInside
    @Target(ElementType.FIELD)
    @Retention(RetentionPolicy.RUNTIME)
    @JsonDeserialize(using = EnumJsonDeserializer.class)
    public @interface JacksonEnum {
    }
    
    
    
    1. 实现类
    
    
    public class EnumJsonDeserializer<T extends Enum<?> & BuzEnum<?>> extends JsonDeserializer<Object> implements ContextualDeserializer {
    
        private Class<T> classType;
    
        public EnumJsonDeserializer() {
    
        }
    
        public EnumJsonDeserializer(Class<T> classType) {
            this.classType = classType;
    
        }
    
        @SneakyThrows
        @Override
        @SuppressWarnings("unchecked")
        public Object deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) {
            JsonNode treeNode = jsonParser.getCodec().readTree(jsonParser);
            try {
                return BuzEnum.findByCode(this.classType, treeNode.asInt()).orElseThrow(() -> new CustomizerException("参数转换失败"));
            } catch (Exception ex) {
                if (treeNode.isTextual()) {
                    return BuzEnum.find(this.classType, e -> treeNode.asText().equals(e.name()))
                            .orElseGet(() ->
                                    BuzEnum.findByValue(this.classType, treeNode.asText())
                                            .orElseThrow(() -> new CustomizerException("参数转换失败"))
                            );
                }
            }
    
            // Node was an empty string
            return null;
        }
    
    
        @Override
        public JsonDeserializer<?> createContextual(DeserializationContext deserializationContext, BeanProperty beanProperty) {
            Class<?> targetClass = beanProperty.getType().getRawClass();
            if (targetClass != null) {
                return new EnumJsonDeserializer(targetClass);
            }
            return this;
        }
    }
    
    
    1. 枚举接口
    
    public interface BuzEnum<T> {
        /**
         * 枚举业务状态值
         *
         * @return
         */
        T getCode();
    
        /**
         * 枚举业务状态描述
         *
         * @return
         */
        String getValue();
        /**
         * 对比是否和code相等,对比地址,值,value转为string忽略大小写对比,text忽略大小写对比
         *
         * @param c code
         * @return 是否相等
         */
        @SuppressWarnings("all")
        default boolean eq(Object c) {
            if (c == null) {
                return false;
            }
            if (c instanceof Object[]) {
                c = Arrays.asList(c);
            }
            return this == c
                    || getCode() == c
                    || getCode().equals(c)
                    || String.valueOf(getCode()).equalsIgnoreCase(String.valueOf(c))
                    || getValue().equalsIgnoreCase(String.valueOf(c)
            );
        }
    
        /**
         * 从指定的枚举类中查找想要的枚举,并返回一个{@link Optional},如果未找到,则返回一个{@link Optional#empty()}
         *
         * @param type      实现了{@link BuzEnum}的枚举类
         * @param predicate 判断逻辑
         * @param <T>       枚举类型
         * @return 查找到的结果
         */
        static <T extends Enum<?> & BuzEnum<?>> Optional<T> find(Class<T> type, Predicate<T> predicate) {
            if (type.isEnum()) {
                for (T each : type.getEnumConstants()) {
                    if (predicate.test(each)) {
                        return Optional.of(each);
                    }
                }
            }
            return Optional.empty();
        }
    
        /**
         * 根据枚举的{@link BuzEnum#getCode()}来查找.
         *
         * @see this#find(Class, Predicate)
         */
        static <T extends Enum<?> & BuzEnum<?>> Optional<T> findByCode(Class<T> type, Object code) {
            return find(type, e -> e.getCode() == code || e.getCode().equals(code) || String.valueOf(e.getCode()).equalsIgnoreCase(String.valueOf(code)));
        }
    
        /**
         * 根据枚举的{@link BuzEnum#getValue()} ()} 来查找.
         *
         * @see this#find(Class, Predicate)
         */
        static <T extends Enum<?> & BuzEnum<?>> Optional<T> findByValue(Class<T> type, String text) {
            return find(type, e -> e.getValue().equalsIgnoreCase(text));
        }
    
        /**
         * 根据枚举的{@link BuzEnum#getCode()},{@link BuzEnum#getValue()}来查找.
         *
         * @see this#find(Class, Predicate)
         */
        static <T extends Enum<?> & BuzEnum<?>> Optional<T> find(Class<T> type, Object target) {
            return find(type, v -> v.eq(target));
        }
    
    
        static <E extends BuzEnum<?>> Optional<E> of(Class<E> type, Object value) {
            if (type.isEnum()) {
                for (E enumConstant : type.getEnumConstants()) {
                    Predicate<E> predicate = e -> e.getCode() == value || e.getCode().equals(value) || String.valueOf(e.getCode()).equalsIgnoreCase(String.valueOf(value));
                    if (predicate.test(enumConstant)) {
                        return Optional.of(enumConstant);
                    }
                }
            }
            return Optional.empty();
        }
    }
    
    1. 使用方式

    image

    1. 能够实现的如下
      image
      image
      image
      image
  • 相关阅读:
    VS2010插件及快捷键设置
    在Windows程序中启用console输出-2016.01.04
    使用VAssistX给文件和函数添加注释-2015.12.31
    windows在远程桌面连接中使用命令行参数
    windows网络编程-2015.12.29
    grep使用
    linux程序调试常用命令
    vim使用笔记
    infusion度量金字塔数据解释
    MVc Forms Membership rolemanage 角色权限验证管理
  • 原文地址:https://www.cnblogs.com/akashicbrother/p/16420749.html
Copyright © 2020-2023  润新知