1.首先编写自定义注解
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DictParam {
/**
* 映射目标属性,为空默认直接映射到field,替换掉原来的field
*
* @return
*/
String targetField() default "";
/**
* 映射来源属性
*
* @return
*/
String field();
/**
* 数据字典类型
*
* @return
*/
String dictType();
}
2.自定义方法注解
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DictHelper {
/**
* 字典转换参数配置
*/
DictParam[] value();
}
3.使用aop的方式处理不同返回值的实体.此处写死了两种方法返回值,如果其他的更好的方式,欢迎大佬留言告诉我.谢谢
@Slf4j
@Aspect
@Component
public class DictHelperAspect {
public static final String PAGE_INFO = "PageInfo";
public static final String GET = "get";
public static final String SET = "set";
@Pointcut("@annotation(com.citycloud.bigdata.biz.clearance.common.dict.DictHelper)")
private void dictHelper() {
}
@Around("dictHelper()")
public Object doAround(ProceedingJoinPoint joinPoint) {
try {
// 执行方法得到结果
Object result = joinPoint.proceed();
//检查允许的字典项
Signature signature = joinPoint.getSignature();
MethodSignature methodSignature = (MethodSignature) signature;
Method method = methodSignature.getMethod();
if (method.isAnnotationPresent(DictHelper.class)) {
DictHelper dictHelper = method.getAnnotation(DictHelper.class);
DictParam[] values = dictHelper.value();
if (values == null || values.length == 0) {
return result;
}
// 字典转换开始(使用反射)
for (DictParam value : values) {
Class<?> clazz = result.getClass();
if (clazz.getName().contains(PAGE_INFO)) {
PageInfo<T> pageInfo = (PageInfo) result;
List<T> list = pageInfo.getList();
for (Object t : list) {
Class<?> voClass = t.getClass();
// 反射调用get方法获取字段值
Method sourceMethod = voClass.getMethod(GET + firstToUppercase(value.field()));
Object fieldValue = sourceMethod.invoke(t);
if (Objects.isNull(fieldValue)) {
continue;
}
Map<String, DictVo> dictVoMap = DictConfig.DICT_MAPPER.get(value.dictType());
if (dictVoMap.isEmpty()) {
continue;
}
// 获取字典值
DictVo dictDo = dictVoMap.get(fieldValue.toString());
// 获取目标方法进行设值
String targetField = StringUtils.isBlank(value.targetField()) ? value.field() : value.targetField();
Method targetMethod = voClass.getMethod(SET + firstToUppercase(targetField), dictDo.getClass());
targetMethod.invoke(t, dictDo);
}
} else {
// 反射调用get方法获取字段值
Method sourceMethod = clazz.getMethod(GET + firstToUppercase(value.field()));
Object fieldValue = sourceMethod.invoke(result);
// 获取字典值
if (Objects.isNull(fieldValue)) {
continue;
}
Map<String, DictVo> dictVoMap = DictConfig.DICT_MAPPER.get(value.dictType());
if (dictVoMap.isEmpty()) {
continue;
}
DictVo dictDo = dictVoMap.get(fieldValue.toString());
// 获取目标方法进行设值
String targetField = StringUtils.isBlank(value.targetField()) ? value.field() : value.targetField();
Method targetMethod = clazz.getMethod(SET + firstToUppercase(targetField), dictDo.getClass());
targetMethod.invoke(result, dictDo);
}
}
}
return result;
} catch (Throwable throwable) {
log.error("error:", throwable);
return null;
}
}
private String firstToUppercase(String str) {
return str.substring(0, 1).toUpperCase() + str.substring(1);
}
4.具体的字典项返回结果的字典项配置文件
@Component
public class DictConfig {
public static Map<String, Map<String, DictVo>> DICT_MAPPER = new HashMap<>();
@Autowired
private DictDao dictDao;
@PostConstruct
public void init() {
List<DictDo> dictDoList = dictDao.selectList(new LambdaQueryWrapper<>(DictDo.class));
List<DictVo> dictVoList = BeanCopyUtils.cloneFromList(dictDoList, DictVo.class);
Map<String, Map<String, DictVo>> resultMap = dictVoList.stream().collect(Collectors.groupingBy(
DictVo::getDictType, Collectors.toMap(DictVo::getDictValue, Function.identity(), (v1, v2) -> v2)));
DICT_MAPPER.putAll(resultMap);
}
}
欢迎大佬给出意见.谢谢