效果:接口會返回orderType,但是這個orderType是枚舉的類型(1,2,3,4),我想多返回一個orderTypeDesc給前端展示,這樣前端就可以直接拿orderTypeDesc使用了。
1. 定義注解
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD})
//作用是將當前類上的注解也追加到目標類上,如果不加的話,目標類及時加了@EnumTranslation注解,也不會集成該注解的所有注解
@JacksonAnnotationsInside
@JsonSerialize(using = EnumTranslationSerialize.class)
public @interface EnumTranslation {//生成的屬性名,不寫默認原名+DescString generateFieldName() default "";//參考的枚舉,會根據改枚舉的code獲取對應的descClass<? 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));}}/*** 序列化規則*/@Overridepublic 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接口的方法,作用是獲取屬性上的枚舉*/@Overridepublic 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;
}