1.创建字典项翻译注解@DictCn
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DictCn {
/**字典编码*/
String code() default "";
/**字典键值*/
String key() default "";
}
2.创建切点注解
@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DictTranslate {
}
3.实现Aspect方法
@Slf4j
@Aspect
@Component
public class DictCnAspect {
private static List BASE_CLASS;
@Around("@annotation(DictTranslate) || @within(DictTranslate)")
public Object run(ProceedingJoinPoint joinPoint) throws Throwable {
Object proceed = joinPoint.proceed();
try {
translate(proceed);
}catch (Exception e){
log.warn("字典项翻译失败",e.getMessage());
}
return proceed;
}
private void translate(Object obj) {
if (ObjectUtil.isNull(obj) || Map.class.isAssignableFrom(obj.getClass())){
return;
}
//处理列表翻译
if (Collection.class.isAssignableFrom(obj.getClass())){
Iterator var8 = ((Collection)obj).iterator();
while(var8.hasNext()) {
Object o = var8.next();
this.translate(o);
}
}
//拿到所有的属性字段 遍历这些字段
for (Field field : getAllFields(obj)) {
field.setAccessible(true);
if (field.isAnnotationPresent(DictCn.class)) {
DictCn annotation = (DictCn)field.getAnnotation(DictCn.class);
String code = annotation.code();
String name = annotation.key();
try {
String key = (String)invokeGet(obj, name);
if (!StrUtil.isEmpty(key)) {
//获取字典项翻译
String value = DictBizCache.getValue(code, key);
//set值
invokeSet(obj, field, value);
}
} catch (Exception e) {
log.error("字典翻译未找到指定的字段{}",e.getMessage());
e.printStackTrace();
}
} else {
try {
Object o = field.get(obj);
if (!Objects.isNull(o) && !isBaseClass(o.getClass())) {
this.translate(o);
}
} catch (IllegalAccessException e) {
e.printStackTrace();
log.error("字典翻译异常");
}
}
}
}
/**set值*/
public static void invokeSet(Object o, Field field, Object value) {
try {
Class clz = o.getClass();
String fieldName = field.getName();
StringBuffer sb = new StringBuffer();
sb.append("set");
sb.append(fieldName.substring(0, 1).toUpperCase());
sb.append(fieldName.substring(1));
Method method = clz.getMethod(sb.toString(), field.getType());
method.invoke(o, value);
} catch (Exception var7) {
var7.printStackTrace();
}
}
/**获取指定字段值*/
public static Object invokeGet(Object o, String fieldName) throws Exception {
Method method = getGetMethod(o.getClass(), fieldName);
return method.invoke(o, (Object[])null);
}
/**获取get方法*/
public static Method getGetMethod(Class objectClass, String fieldName) throws Exception {
StringBuffer sb = new StringBuffer();
sb.append("get");
sb.append(fieldName.substring(0, 1).toUpperCase());
sb.append(fieldName.substring(1));
return objectClass.getMethod(sb.toString());
}
/**拿到所有的属性字段*/
public static Field[] getAllFields(Object object) {
Class clazz = object.getClass();
ArrayList fieldList;
for(fieldList = new ArrayList(); clazz != null; clazz = clazz.getSuperclass()) {
fieldList.addAll(new ArrayList(Arrays.asList(clazz.getDeclaredFields())));
}
Field[] fields = new Field[fieldList.size()];
fieldList.toArray(fields);
return fields;
}
public static boolean isBaseClass(Class clz) {
return BASE_CLASS.contains(clz) ;
}
public static Class getGenericCls(Field field) {
try {
Type genericType = field.getGenericType();
if (!Objects.isNull(genericType) && genericType instanceof ParameterizedType) {
ParameterizedType type = (ParameterizedType)genericType;
Type actualTypeArguments = type.getActualTypeArguments()[0];
if (actualTypeArguments instanceof Class) {
return (Class)actualTypeArguments;
}
}
} catch (Exception var4) {
var4.printStackTrace();
}
return null;
}
static {
BASE_CLASS = ListUtil.toList(
String.class,
BigDecimal.class,
Date.class,
Integer.TYPE, Integer.class,
Boolean.TYPE, Boolean.class,
Float.TYPE, Float.class,
Double.TYPE, Double.class,
Long.TYPE, Long.class,
Character.TYPE, Character.class,
Kv.class,
Map.class,
null);
}
}
4.使用
4.1 Constructor接口添加注解
/**详情*/
@GetMapping("detail")
@DictTranslate
public R<InfoVO> detailInfo(@RequestParam(value = "id") @NotNull(message = "主键ID不能为空") Long id) {
return R.data(testService.detailInfo(id));
}
4.2 返回实体添加注解
@Data
public class TaskInfoVO {
/**主键id*/
private Long id;
/**类型*/
private String taskType;
/**code为字典项大类code key为需要翻译的字段名*/
@DictCn(code = TypeKeyConstant.party_building_activity_type,key = "taskType")
private String taskTypeCn;
}