效果:接口会返回orderType,但是这个orderType是枚举的类型(1,2,3,4),我想多返回一个orderTypeDesc给前端展示,这样前端就可以直接拿orderTypeDesc使用了。
1. 定义注解
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD})
//作用是将当前类上的注解也追加到目标类上,如果不加的话,目标类及时加了@EnumTranslation注解,也不会集成该注解的所有注解
@JacksonAnnotationsInside
@JsonSerialize(using = EnumTranslationSerialize.class)
public @interface EnumTranslation {
//生成的属性名,不写默认原名+Desc
String generateFieldName() default "";
//参考的枚举,会根据改枚举的code获取对应的desc
Class<? extends Enum<?>> targetEnum() ;
}
2. 定义EnumTranslationSerialize类
EnumTranslationSerialize继承了JsonSerializer,实现了ContextualSerializer,用于序列化时多生成一个字段返回。
ContextualSerializer的作用:为了在序列化时获取属性上的注解信息,然后根据注解信息重新创建EnumTranslationSerialize来序列化,这样就能根据注解的配置来序列化了。
@Slf4j
public class EnumTranslationSerialize<E> extends JsonSerializer<Object> implements ContextualSerializer {
private String targetFieldName;
private LinkedHashMap<String, String> enumMap;
public EnumTranslationSerialize() {
//需要空构造方法,请勿删除
}
/**
* 构造方法,获取当前属性名,生成的属性名,目标枚举
*/
public EnumTranslationSerialize(String fieldName, String targetFieldName, Class enumClass) {
if (StringUtils.isNotBlank(targetFieldName)) {
this.targetFieldName = targetFieldName;
} else {
this.targetFieldName = fieldName + "Name";
}
enumMap = new LinkedHashMap<>();
try {
Method getCode = enumClass.getMethod("getCode");
Method getDesc = enumClass.getMethod("getDesc");
for (Object everyEnum : EnumUtil.getEnumMap(enumClass).values()) {
enumMap.put(getCode.invoke(everyEnum).toString(), getDesc.invoke(everyEnum).toString());
}
} catch (Exception e) {
log.error(ExceptionUtils.getStackTrace(e));
}
}
/**
* 序列化规则
*/
@Override
public void serialize(Object o, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
if (Objects.isNull(o)) {
return;
}
try {
String codeValue = o.toString();
jsonGenerator.writeString(codeValue);
String value = enumMap.get(codeValue);
//多写入一个属性
if (Objects.nonNull(value)) {
jsonGenerator.writeFieldName(this.targetFieldName);
jsonGenerator.writeObject(value);
}
} catch (Exception e) {
log.error(ExceptionUtils.getStackTrace(e));
}
}
/**
* ContextualSerializer接口的方法,作用是获取属性上的枚举
*/
@Override
public JsonSerializer<?> createContextual(SerializerProvider serializerProvider, BeanProperty beanProperty) throws JsonMappingException {
if (beanProperty != null) {
EnumTranslation t = beanProperty.getAnnotation(EnumTranslation.class);
if (t != null) {
return new EnumTranslationSerialize<>(beanProperty.getName(), t.targetFieldName(), t.enumC());
}
}
return serializerProvider.findNullValueSerializer(beanProperty);
}
}
3. 使用
@Data
public class OrderVO {
@Schema(description = "订单类型")
@EnumTranslation(generateFieldName = "orderTypeDesc", enumC = OrderType.class)
private Long orderType;
}