1.定义注解

import java.lang.annotation.*;@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Dict {/*** 字典类型**/String type();/*** 字典存放后缀* 默认 "Text"* 例 原始字段名:type  翻译储存的字段名:typeText**/String suffix() default "Text";/*** 是否级联(原储存指使用“,”连接)* 默认 false**/boolean cascader() default false;/*** 级联时 中文字段是否全部翻译* true 全部* false 最后一级**/boolean all() default true;/*** 级联时 翻译值的连接符**/String connector() default "/";
}

2.定义切面注解

import java.lang.annotation.*;@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DictCovert {}

3.切面处理

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.Lists;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;@Slf4j
@Aspect
@Component
public class DictCovertAopAspect {@Resourceprivate DictService dictService;/*** 表示匹配带有自定义注解的方法 根据 DictCovert 存放包名设置*/@Pointcut("@annotation(com.**.DictCovert)")public void pointcut() {}/*** 环绕通知注解匹配,处理字典翻译*/@Around("pointcut()")public Object aroundAdvice(ProceedingJoinPoint point) throws Throwable {//返回结果Object result = point.proceed();return this.parsedResult(result);}/*** 对方法的返回结果 进行字典翻译处理*/private Object parsedResult(Object result) throws Exception {//判断空if (Objects.isNull(result)) {return null;}//判断结果类型if (result instanceof List) {//LIST类型List<Object> list = Lists.newArrayList();for (Object obj : (List<Object>) result) {list.add(dictService.parsedDict(obj));}return list;} else if (result instanceof QueryPageResultDTO) {//自定义的分页返回结果集类型  实际结果在 list字段中。 处理和LIST一致QueryPageResultDTO pageResult = (QueryPageResultDTO) result;List<Object> list = Lists.newArrayList();for (Object obj : pageResult.getList()) {list.add(dictService.parsedDict(obj));}//分页数据中 重新放入结果pageResult.setList(list);return pageResult;} else {//单实例对象类型return dictService.parsedDict(result);}}
}

4.字典的实现类

import org.apache.commons.compress.utils.Lists;
import org.springframework.stereotype.Service;import javax.annotation.Resource;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;@Slf4j
@Service
public class DictService {@Resourceprivate DictCache dictCache;/*** 字典翻译* @param obj*/public Object parsedDict(Object obj) throws Exception {Field[] fields = obj.getClass().getDeclaredFields();//非空判断if (ObjectUtil.isEmpty(fields)) {return obj;}//转换成mapMap map = JsonUtils.obj2map(obj);for (Field field : fields) {//判断每一个字典是否有Dict注解if (Objects.nonNull(field.getAnnotation(Dict.class))) {Dict dict = field.getAnnotation(Dict.class);String fieldName = field.getName();Object value = map.get(fieldName);map.put(fieldName + dict.suffix(), getDictText(dict, value));}}//重新返回构建对象String obj2json = JsonUtils.obj2json(map);return JsonUtils.json2obj(obj2json, obj.getClass());}/*** 值获取字典翻译* @param dict* @param value* @return*/private String getDictText(Dict dict, Object value) {//空判断if (Objects.isNull(value)) {return "";}// 值都是以字符串形式储存String val = value.toString();//根据字典类型 获取字段对应的翻译LIST 本处使用了缓存机制(5分钟),防止重复获取//DictDTO  仅2个  name   value  List<DictDTO> dicts = dictCache.listDict(dict.type());if (CollectionUtil.isEmpty(dicts)) {return "";}//根据连接符拆分成LIST  List<String> keys = Arrays.asList(val.split(","));//所有翻译  去掉空List<String> texts = keys.stream().map(v -> dicts.stream().filter(t -> t.getValue().equals(v)).findFirst().map(DictDTO::getName).orElse(null)).filter(StringUtils::isNotEmpty).collect(Collectors.toList());//是否全展示if (dict.all()) {return StringUtils.join(texts, dict.connector());} else {//仅最后一级return texts.get(texts.size() - 1);}}
}

5.使用方式

1、对象中需要翻译的属性加上 @Dict 注解

例:

import lombok.Data;
import lombok.ToString;import java.util.Date;@Data
@ToString
public class UserResultDTO{/*** UID*/private Long uid;/*** 姓名*/private String name;/*** 用户性别  1 男  2 女* 字典类型 SEX_TYPE*/@Dict(type = "SEX_TYPE", suffix = "Text")private String sex;/*** 用户性别翻译 此属性非数据库储存字段 * 属性名称根据 上面的注解中的 suffix 确定 * sex + suffix  即 sexText*/private String sexText;/*** 爱好  1 篮球  2 乒乓球 3 羽毛球* 字典类型 AH_TYPE*/@Dict(type = "AH_TYPE", suffix = "List", cascader = true, connector = "、")private String ah;/*** 爱好翻译 此属性非数据库储存字段 * 属性名称根据 上面的注解中的 suffix 确定 * ah + suffix  即 ahList*/private String ahList;……省略其他属性
}

2、service层方法上加上 @DictCovert 注解

import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;@Service
public class UserServiceImpl implements UserService {@Resourceprivate UserDao userDao;/*** 获取用户信息** @param uid UID*/@Override@DictCovertpublic UserResultDTO getUserByUid(Long uid){User user = userDao.getUserByUid(uid);if (Objects.isNull(user)) {throw new *****;}//实例对象转换 ModelDTOConverter 自己写的通用实例转换工具return ModelDTOConverter.from(model, UserResultDTO.class)}
}

3、 Controller省略

6、得到的结果

{code: 0,msg: "成功",data: {uid: 1,name: "##",sex: "1",sexText: "男",ah: "1,2,3",ahList: "篮球、乒乓球、羽毛球"}
}

至此,字典翻译处理完毕!请指正~

java实现自定义注解翻译字典相关推荐

  1. java 实现自定义注解实现字典翻译

    1.定义接口 /** * 数据字典注解 */ @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interf ...

  2. Java AOP自定义注解

    一.背景 在之前文章:Java注解详解中,主要介绍了注解的含义.作用.以及常用的各类注解.今天主要介绍在Springboot中如何实现一个自定义注解,通过自定义注解去实现一些定制化的需求. 二.了解元 ...

  3. java之自定义注解的完整使用

    小坏java自定义注解的完整使用 一.何为java注解之道 1.java 注解的理解之道 2.java 注解的使用示例之道 3.Java 如何自定义注解之道 4.java 元注解之道 5.java 如 ...

  4. Java中自定义注解的使用

    Java中自定义注解的使用 一般来说,市面上有一些的框架,企业都不会直接拿过来就用,通过会做二次开发或封装,为了更加适配自己的开发规范和业务.那么在封装或适配的过程中,自定义注解就起着比较重要的作用. ...

  5. Java实现自定义注解

    前言 (1)Java实现自定义注解其实很简单,跟类定义差不多,只是属性的定义可能跟我们平时定义的属性略有不同,这里会给大家详解,先来看代码: @Target(ElementType.FIELD) @R ...

  6. AOP+自定义注解实现字典翻译

    目录 需求: 结果展示 : 代码实现 : 需求: 一般情况下数据库表中字段对应的是字典值,但在查询或导出时需要展示字典名,若每次字典转换时都需要关联字典表查询,而且导出时还需要在做一次数据转换,这样处 ...

  7. 谈谈 Java 中自定义注解及使用场景

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 作者:快给我饭吃 www.jianshu.com/p/a7bedc ...

  8. Java基于自定义注解的面向切面的实现

    目的:实现在任何想要切的地方添加一个注解就能实现面向切面编程 自定义注解类 @Target({ElementType.PARAMETER, ElementType.METHOD}) @Retentio ...

  9. [转] Java @interface 自定义注解

    [From] http://blog.csdn.net/afterlife_qiye/article/details/53748973 1. 注解的好处 注解可以替代配置文件完成对某些功能的描述,减少 ...

最新文章

  1. 处理机调度的性能准则
  2. Windows 下 tail 查看日志命令工具分享
  3. TCP/IP协议簇简介
  4. Leetcode389
  5. LeetCode 6062. 设计一个 ATM 机器
  6. 机器学习和ML.NET简介-第1部分
  7. Mac安装prometheus+grafana监控
  8. python如何提高性能_python – 如何在这个短代码中提高numpy性能...
  9. (四) Session管理 --《springboot与shiro整合》
  10. 如何改变证件照大小?三步搞定
  11. HDU - Shaolin(STL)
  12. 信息化、数字化、智能化到底有什么区别
  13. 网络基础知识:10M、50M、100M宽带下载速率一般是多少?
  14. AMBER免费申请流程
  15. qgraphicsitem 复制副本,QGraphicsItem:调用paint函数时
  16. 2021年四川高考成绩排名查询,四川高考排名查询方法,2021年四川高考成绩位次全省排名查询...
  17. Oracle转PostgreSQL之start with / connect by
  18. 智能家居设备安全分析技术综述
  19. h5页面是html5么,H5是什么?5分钟就能全面了解什么是html5页面
  20. zkSNARKs 合约库「输入假名」漏洞致众多混币项目爆雷

热门文章

  1. 【Redis】Redis7.0新特性汇总(详细)
  2. python可以用来开发前端吗_python能开发前端吗
  3. Linux-04-文件管理(包括压缩与打包)、用户管理、提取IP地址
  4. 蓝旭工作室2022第五次讨论班Javascript基础
  5. google地图学习笔记(1)
  6. 苹果春季发布会提前曝光:紫色iPhone 13 Pro冲上热搜,SE3将搭载A15芯片
  7. 架构设计师(Architect)的专业与角色(转载)
  8. Hadoop+Kafka相关重点复习
  9. 基于MQTT协议的 org.eclipse.paho.client.mqttv3 源码学习(二)
  10. C语言文件操作系统实验