springboot 枚举序列化时,动态添加翻译值
前提:了解springboot与FastJson的整合以及相关的全局配置
一、需求
- 后端返回给前端值,添加枚举值翻译,如:
sex=1
,本来的json是{"sex":1}
,期望是:{"sex":1,"sexName":"男"}
二、分析
- 在json序列化时,把序列化后的字符串加上
xxxName
属性,根据FastJson的用法,可以通过继承AfterFilter
来实现
三、实现思路
-
定义转换过滤器,继承
com.alibaba.fastjson2.filter.AfterFilter
,重写方法writeAfter
方法 -
自定义注解
@EnumDescribe
(value
=将要注入的枚举类)
@Retention(RetentionPolicy.RUNTIME)
public @interface EnumDescribe {
/**
* 继承EnumName接口的枚举类
*
* @return {@link Class}<{@link ?} {@link extends} {@link IEnumDescribe}>
*/
Class<? extends IEnumDescribe<?>> value();
/**
* 前缀
*
* @return {@link String}
*/
String prefix() default "";
/**
* 后缀
*
* @return {@link String}
*/
String suffix() default "Name";
}
-
如果序列的类的包名前缀是:
com.xxxxx
,那么就进行处理 -
根据当前序列化的类,获取其所有属性
-
判断属性是否有注解
@EnumDescribe
-
如果有注解,那么获取的注解的
value
(枚举类
) -
根据当前类的当前
属性值
与枚举类中各个元素的值
进行比较 -
如果相等,则为当前序列化对象写入
(key,value)
(key
=枚举元素属性名+Name
value
=枚举元素的描述值·
) -
以上代码描述:
public class EnumConvertAfterFilter extends AfterFilter {
@Override
public void writeAfter(Object object) {
Class<?> objectClass = object.getClass();
if (objectClass.getName().startsWith("com.xxxx") && ClassUtil.isNormalClass(objectClass)) {
Field[] declaredFields = objectClass.getDeclaredFields();
for (Field field : declaredFields) {
EnumDescribe annotation = field.getAnnotation(EnumDescribe.class);
if (annotation != null) {
try {
field.setAccessible(true);
Class<? extends IEnumDescribe<?>> clazz = annotation.value();
IEnumDescribe<?>[] enumConstants = clazz.getEnumConstants();
for (IEnumDescribe<?> enumConstant : enumConstants) {
if (enumConstant.getValue().equals(field.get(object))) {
String key = field.getName().concat(annotation.suffix());
if (StringUtils.hasText(annotation.prefix())) {
key = StrUtil.upperFirstAndAddPre(key, annotation.prefix());
}
super.writeKeyValue(key, enumConstant.getDescription());
break;
}
}
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
}
}
}
}
- 把转换过滤器放入
FastJsonConfig
的配置中,然后放在入转换器中,自定义转换器
@Bean
@ConditionalOnMissingBean(FastJsonHttpMessageConverter.class)
public FastJsonHttpMessageConverter converter() {
FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter();
FastJsonConfig config = new FastJsonConfig();
// 重点
config.setWriterFilters(new EnumConvertAfterFilter());
converter.setFastJsonConfig(config);
return converter;
}
四、用法
@EnumDescribe(EnumSex.class)
private Integer sex;
五、相关枚举类需要实现IEnumDescribe
public interface IEnumDescribe<T> {
/**
* 获取id
*
* @return {@link Integer}
*/
T getValue();
/**
* 获取名字
*
* @return {@link String}
*/
String getDescription();
}
注:
- 相关FastJson文档:https://www.w3cschool.cn/fastJson/FastJson-aiserializefilter.html
- 相关springboot与FastJson整合文档:https://blog.csdn.net/lrb0677/article/details/125287043
如有描述不清楚的地方,欢迎留言,我会及时回复