java通過注解翻譯字典的實(shí)現(xiàn)示例
最近在寫代碼時(shí)遇到一個(gè)需要將entity字段通過字典翻譯成真實(shí)值的場景,原來的做法是通過主表字段和字典表關(guān)聯(lián)的形式,當(dāng)一個(gè)需要大量翻譯的場景時(shí),大量的關(guān)聯(lián)會(huì)造成sql閱讀的不友好,所以就在想有什么可以偷懶的方法。。。
首先一個(gè)想法就是通過注解,實(shí)例化entity時(shí)就可以同步翻譯了。
先自定義注解
@Target({ElementType.FIELD,ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface DictCovert { ? ? /** ? ? ?* 字典key ? ? ?* @return ? ? ?*/ ? ? String key() default ""; ? ? /** ? ? ?* 是否使用redis ? ? ?* @return ? ? ?*/ ? ? boolean redis() default false; }
然后在需要轉(zhuǎn)換的entity屬性上加上注解和該屬性的key
/** * 性別 */ @DictCovert(key = "gender",redis = true) private Integer gender;
有了注解,首先想到的就是通過AOP去切該注解@Pointcut("@annotation(*.*.*.DictCovert)"),捕獲到切點(diǎn)時(shí)同步處理數(shù)據(jù)就行
趕緊寫好代碼運(yùn)行,發(fā)現(xiàn)沒有如愿以償,因?yàn)槲覀冏远x的注解加在了entity上,但是entity并沒有交給spring管理,所以切點(diǎn)根本沒有奏效,草(一種植物)??!。。。。。
于是又想到了通過自定義MessageConverter的形式捕獲注解處理,然后依舊是草(一種植物)?。。?!
最終最終還是找到通往羅馬的路了??
通過注解@ControllerAdvice處理全局的數(shù)據(jù),然后繼承ResponseBodyAdvice接口重寫beforeBodyWrite方法,處理數(shù)據(jù)
直接貼代碼(代碼有點(diǎn)長,個(gè)人水平有限,輕噴??)
@ControllerAdvice @Slf4j public class DictCovertHandler implements ResponseBodyAdvice { ? ? @Autowired ? ? private RedisTemplate redisTemplate; ? ? @Autowired ? ? private ISysDicService sysDicService; ? ? private final String DICTDIR = "DICT:"; ? ? @Override ? ? public boolean supports(MethodParameter returnType, Class converterType) { ? ? ? ? //直接為true,所有返回結(jié)果都應(yīng)該檢驗(yàn) ? ? ? ? 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(); ? ? ? ? ? ? //未分頁結(jié)果 ? ? ? ? ? ? if(resValue instanceof ?ArrayList){ ? ? ? ? ? ? ? ? resList =(ArrayList) resValue; ? ? ? ? ? ? } ? ? ? ? ? ? //分頁結(jié)果 ? ? ? ? ? ? if(resValue instanceof Page){ ? ? ? ? ? ? ? ? resList = ((Page<?>) resValue).getRecords(); ? ? ? ? ? ? } ? ? ? ? ? ? //非查詢結(jié)果 ? ? ? ? ? ? if(CollectionUtil.isEmpty(resList)){ ? ? ? ? ? ? ? ? return ?body; ? ? ? ? ? ? } ? ? ? ? ? ? List<Map<String,Object>> resultList = new ArrayList(); ? ? ? ? ? ? for (Object entity : resList) { ? ? ? ? ? ? ? ? ?//拿到bean將其轉(zhuǎn)換為map輸出 ? ? ? ? ? ? ? ? ?Map<String,Object> map = BeanUtil.beanToMap(entity); ? ? ? ? ? ? ? ? //獲取字段列表 ? ? ? ? ? ? ? ? Field[] fields = entity.getClass().getDeclaredFields(); ? ? ? ? ? ? ? ? if(fields.length != 0){ ? ? ? ? ? ? ? ? ? ? for (Field field : fields) { ? ? ? ? ? ? ? ? ? ? ? ? //存放真實(shí)值 ? ? ? ? ? ? ? ? ? ? ? ? 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加載字典真實(shí)信息 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 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(); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //將結(jié)果塞入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; ? ? ? ? } ? ? } }
最后在返回值中會(huì)有一個(gè)帶有String的屬性,那就是翻譯后的值
到此這篇關(guān)于java通過注解翻譯字典的實(shí)現(xiàn)示例的文章就介紹到這了,更多相關(guān)java 注解翻譯字典內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
使用kotlin編寫spring cloud微服務(wù)的過程
這篇文章主要介紹了使用kotlin編寫spring cloud微服務(wù)的相關(guān)知識(shí),本文給大家提到配置文件的操作代碼,給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-09-09java中i=i++和j=i++的區(qū)別小結(jié)
這篇文章主要給大家介紹了關(guān)于java中i=i++和j=i++區(qū)別的相關(guān)資料,文中通過圖文介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-04-04Java設(shè)計(jì)模式之享元模式實(shí)例詳解
這篇文章主要介紹了Java設(shè)計(jì)模式之享元模式,結(jié)合實(shí)例形式詳細(xì)分析了享元模式的概念、功能、定義及使用方法,需要的朋友可以參考下2018-04-04Java web數(shù)據(jù)可視化實(shí)現(xiàn)原理解析
這篇文章主要介紹了Java web數(shù)據(jù)可視化實(shí)現(xiàn)原理解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-03-03解析MyBatis源碼實(shí)現(xiàn)自定義持久層框架
這篇文章主要介紹了手撕MyBatis源碼實(shí)現(xiàn)自定義持久層框架,涉及到的設(shè)計(jì)模式有Builder構(gòu)建者模式、??模式、代理模式,本文通過示例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2022-05-05使用Vue+Spring Boot實(shí)現(xiàn)Excel上傳功能
這篇文章主要介紹了使用Vue+Spring Boot實(shí)現(xiàn)Excel上傳,需要的朋友可以參考下2018-11-11