java系统实体进行枚举类统一转换翻译
在日常项目开发中,不免都会用到一些数据字典的信息,以及前端展示的时候通常也需要把这些数据字典值转换成具体字典文本信息。遇到这种场景通常都是后端把字典的文本转换好一起返回给前端,前端只需要直接展示即可。一般情况下后端可能需要单独给返回对象创建一个字段来存储对应的字典文本值,然后进行手动的处理,这种方式通常比较繁琐,在字段多的时候会增加更多的工作量。
所以我们这次目的是利用java反射机制跟自定义注解功能实现了这一自动转换过程,不需要在对象中定义存放字典文本的字段,只需要在字段上使用特定的注解配置,通过调用方法来完成转换工作。
一、首先我们先创建一个注解
@Target(ElementType.FIELD)@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface AutoEnum {
/**
* 需要翻译说明的枚举路径
* @return
*/
String path() default "";
/**
* 对应翻译后返回字段的名称
* @return
*/
String fieldName() default "";
}
二、然后在实体类里对应需要翻译的属性上写上我们定义的注解如下
@Data@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
public class ServiceOrgAreasExamine implements Serializable {
private static final long serialVersionUID = 1L;
private Integer id;
@AutoEnum(path = "com.aspect.enums.ActivitiesAttributeEnum",fieldName = "areasId")
private Integer organId;
private String organIdV;
@AutoEnum(path = "com.aspect.enums.ExamineStatusEnum")
private Integer examineStatus;
private String examineStatusV;
上面的注解中的path是我们需要翻译的枚举类的路径,fieldName是我们翻译后用哪个字段来回显。如果不填写默认本字段来显示翻译。
三 需要翻译的枚举类如下
/*** 活动类型枚举类
*/
@Getter
@AllArgsConstructor
public enum ActivitiesAttributeEnum {
OFFLINE("1", "线下活动"),
CONSULT("2", "活动咨询");
private final String code;
private final String desc;
}
/*** 服务区域审核状态枚举类
*/
@Getter
@AllArgsConstructor
public enum ExamineStatusEnum {
PENDING_REVIEW(0, "待审核"),
REFUSE(1, "已拒绝"),
SERVING(2, "服务中"),
DISMISSAL(3, "解除服务");
private final Integer code;
private final String desc;
}
四、以上准备工作完成。最重要的就是如何通过反射进行赋值了。
import com.aspect.annotation.AutoEnum;import java.io.Serializable;
import java.lang.reflect.Field;
import java.util.List;
import java.util.Map;
/**
* @Author: cq
* @Description
* @Date Create in 2:44 PM 2021/12/27.
*/
public class InterprectChineseUtils<T extends Serializable> {
/**
* 通过注解将传入的实体翻译成中文的说明 实体中对应注解@AutoEnum
* @param t 需要将枚举翻译成中文说明的实体
*/
public void reflexEnum(T t) {
Class clas = t.getClass();
for (Field f : t.getClass().getDeclaredFields()) {
Object value = null;
try {
//对于private的属性,如果不解锁,那么将无法访问,会报错
f.setAccessible(true);
//通过反射的字段获取实体中的值
value = f.get(t);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
//获取注解的信息
AutoEnum anno2 = f.getAnnotation(AutoEnum.class);
if(anno2!=null&&value!=null) {
//注解的path
String path = anno2.path();
//注解的fieldName
String fieldName = anno2.fieldName();
//通过value过去枚举中对应的中文说明
String enumValues = InterprectChineseUtils.enumExplain(path, value.toString());
try {
//通过注解中写的fieldName,给需要赋值的字段赋值
Field fv = null;
if(!"".equals(fieldName)) {
fv = clas.getDeclaredField(fieldName);
}
else {
fv = f;
}
//对于private的属性,如果不解锁,那么将无法访问,会报错
fv.setAccessible(true);
fv.set(t,enumValues);
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
}
/**
* 通过枚举路径跟值获取对应的中文说明
* @param name 枚举的class路径
* @param code 对应的枚举值
* @return
*/
public static String enumExplain(String name, String code) {
try {
Class clazz = Class.forName(name);
List<Map<String, Object>> list = EnumUtils.toMapList(clazz);
for (Map map : list) {
if (map.get("code").toString().equals(code)) {
return map.get("desc").toString();
}
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return "";
}
}
五、另外附上EnumUtils类用于将枚举类转换成list方便遍历出想要的desc说明内容。
/*** @Author: cq
* @Description 枚举工具类
* @Date Create in 3:43 PM 2020/4/26.
*/
public class EnumUtils {
private static final String DEFAULT_ENUM_NAME = "name";
/**
* 首字母转大写
*
* @param s 需要操作的字符串
* @return 转换后结果
*/
private static String toUpperCaseFirstOne(String s) {
if (Character.isUpperCase(s.charAt(0))) {
return s;
} else {
return Character.toUpperCase(s.charAt(0)) + s.substring(1);
}
}
/**
* 枚举转List格式
*
* @param targetEnumClazz 目标枚举Clazz
* @return 装换结果
*/
public static List<Map<String, Object>> toMapList(Class targetEnumClazz) {
return toList(targetEnumClazz, DEFAULT_ENUM_NAME);
}
/**
* 枚举转List格式
*
* @param targetEnumClazz 目标枚举Clazz
* @param enumName 返回JSON中枚举名称对应的Key
* @return 转换结果
*/
public static List<Map<String, Object>> toList(Class targetEnumClazz, String enumName) {
try {
//获取方法
Method[] methods = targetEnumClazz.getMethods();
Field[] fields = targetEnumClazz.getDeclaredFields();
List<Field> fieldList = new ArrayList();
for (Method method : methods) {
for (Field field : fields) {
if (method.getName().endsWith(toUpperCaseFirstOne(field.getName()))) {
fieldList.add(field);
}
}
}
List<Map<String, Object>> resultList = new ArrayList();
//获取值
Enum[] enums = (Enum[]) targetEnumClazz.getEnumConstants();
for (Enum e : enums) {
Map<String, Object> eMap = new HashMap();
String enumNameValue = e.name();
for (Field field : fieldList) {
field.setAccessible(true);
if (field.getName().equals(enumName)) {
enumNameValue = enumNameValue + ";" + field.get(e);
} else {
eMap.put(field.getName(), field.get(e));
}
}
if (enumNameValue.startsWith(";")) {
enumNameValue = enumNameValue.substring(1);
}
eMap.put(enumName, enumNameValue);
resultList.add(eMap);
}
return resultList;
} catch (RuntimeException | IllegalAccessException e) {
}
return null;
}
}
以上就是全部实现的代码了。我们来写一个测试类测试下效果
public class test {@Test
public void tests(){
InterprectChineseUtils <ServiceOrgAreasExamine> interprectChineseUtils = new InterprectChineseUtils();
ServiceOrgAreasExamine serviceOrgAreasExamine = new ServiceOrgAreasExamine();
serviceOrgAreasExamine.setExamineStatus("1");
serviceOrgAreasExamine.setOrganId(1);
interprectChineseUtils.reflexEnum(serviceOrgAreasExamine);
System.out.println(serviceOrgAreasExamine.toString());
}
}
运行后内容如下
至此大功告成。再也不用写一堆麻烦的判断进行翻译说明了,用起来就很方便了。前端直接就能拿到想要显示的内容了~
小小功能完成了,如果转载请标明出处。
以上是 java系统实体进行枚举类统一转换翻译 的全部内容, 来源链接: utcz.com/z/394843.html