基于jackson 注解 入参 枚举 反序列化 实操
作者:互联网
浪费俩小时写了这个,不多说 直接上代码。
- 注解
@Documented
@JacksonAnnotationsInside
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@JsonDeserialize(using = EnumJsonDeserializer.class)
public @interface JacksonEnum {
}
- 实现类
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;
}
}
- 枚举接口
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();
}
}
- 使用方式
- 能够实现的如下
标签:return,getCode,Optional,BuzEnum,入参,jackson,序列化,type,Class 来源: https://www.cnblogs.com/akashicbrother/p/16420749.html