java通过注解翻译字典的实现示例(java常用的注解)

网友投稿 666 2022-08-02


最近在写代码时遇到一个需要将entity字段通过字典翻译成真实值的场景,原来的做法是通过主表字段和字典表关联的形式,当一个需要大量翻译的场景时,大量的关联会造成sqlhttp://阅读的不友好,所以就在想有什么可以偷懒的方法。。。

首先一个想法就是通过注解,实例化entity时就可以同步翻译了。

先自定义注解

@Target({ElementType.FIELD,ElementType.METHOD})

@Retention(RetentionPolicy.RUNTIME)

@Documented

public @interface DictCovert {

/**

* 字典key

* @return

*/

String key() default "";

/**

* 是否使用redis

* @return

*/

boolean redis() default false;

}

然后在需要转换的entity属性上加上注解和该属性的key

/**

* 性别

*/

@DictCovert(key = "gender",redis = true)

private Integer gender;

有了注解,首http://先想到的就是通过AOP去切该注解@Pointcut("@annotation(*.*.*.DictCovert)"),捕获到切点时同步处理数据就行

赶紧写好代码运行,发现没有如愿以偿,因为我们自定义的注解加在了entity上,但是entity并没有交给spring管理,所以切点根本没有奏效,草(一种植物)!!。。。。。

于是又想到了通过自定义MessageConverter的形式捕获注解处理,然后依旧是草(一种植物)!!!!

最终最终还是http://找到通往罗马的路了

通过注解@ControllerAdvice处理全局的数据,然后继承ResponseBodyAdvice接口重写beforeBodyWrite方法,处理数据

直接贴代码(代码有点长,个人水平有限,轻喷)

@ControllerAdvice

@Slf4j

public class DictCovertHandler implements ResponseBodyAdvice {

@Autowired

private RedisTemplate redisTemplate;

@Autowired

private ISysDicService sysDicService;

privhttp://ate final String DICTDIR = "DICT:";

@Override

public boolean supports(MethodParameter returnType, Class converterType) {

//直接为true,所有返回结果都应该检验

return true;

}

@Override

public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {

try{

Result result = (Result)body;

//获取返回值列表

List> resList =new ArrayList<>();

Object resValue = result.getData();

//未分页结果

if(resValue instanceof ArrayList){

resList =(ArrayList) resValue;

}

//分页结果

if(resValue instanceof Page){

resList = ((Page>) resValue).getRecords();

}

//非查询结果

if(CollectionUtil.isEmpty(resList)){

return body;

}

List> resultList = new ArrayList();

for (Object entity : resList) {

//拿到bean将其转换为map输出

Map map = BeanUtil.beanToMap(entity);

//获取字段列表

Field[] fields = entity.getClass().getDeclaredFields();

if(fields.length != 0){

for (Field field : fields) {

//存放真实值

String realValue =null;

//获取注解列

DictCovert dictCovert = field.getAnnotation(DictCovert.class);

if(!Objects.isNull(dictCovert)){

String dictKey = dictCovert.key();

//是否使用redis,default:false

boolean redis = dictCovert.redis();

String fieldName = field.getName();

String methodName = "get"+dictKey.substring(0,1).toUpperCase()+dictKey.substring(1,dictKey.length());

Method method = entity.getClass().getMethod(methodName,null);

//获取字典原始值

Object value =method.invoke(entity,null);

if(Objects.isNull(value)){

continue;

}

String redisKey= dictKey+"_"+value;

//使用redis

if(redis){

//从redis加载字典真实信息

realValue = (String) redisTemplate.opsForValue().get(DICTDIR+redisKey);

}

if(StrUtil.isBlank(realValue)){

SysDic sysDic = sysDicService.getById(Integer.parseInt(value.toString()));

if(!Objects.isNull(sysDic)){

realValue = sysDic.getDictLabel();

//将结果塞入redis

redisTemplate.opsForValue().set(DICTDIR+redisKey,realValue);

}

}

map.put(fieldName+"String",realValue);

}

}

}

resultList.add(map);

}

result.setData(resultList);

return result;

}catch (Exception e ){

//翻译失败返回原来的值

log.error("字典翻译失败",e);

return body;

}

}

}

最后在返回值中会有一个带有String的属性,那就是翻译后的值


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:java实现简易的计算器界面(java设计一个简单的计算器界面)
下一篇:Java实现简易界面通讯录(java实现一个简易的通讯录)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~