一直以来,前端展示字典一般以中文展示为主,若在表中存字典值中文,当字典表更改字典值对应的中文,会造成数据不一致,为此设置冗余字段并非最优方案,若由前端自己写死转义,不够灵活,若在业务代码转义,臃肿也不够通用,从网络上了解到注解、AOP是一种不错的解决方案,主要有两种方式:
1、通过注解获取结果集转为JSON字符串,通过正则查找附加字段;
2、通过获取结果集中相关字段上注解,此种方法有两个需要解决的问题,父类继承字段、嵌合对象难以解决获取对应注解字段问题,解决起来均比较麻烦;
因此本文采用第一种方法,能有效规避第二种方法相关问题,做到逻辑相对简单,引入缓存提高效率。
一、新建注解
标注方法上使用
1 @Retention(RetentionPolicy.RUNTIME)2 @Target(ElementType.METHOD)3 @Documented4 public @interface TranslationDict {5 FieldParam[] value();6 }
注解参数:FieldParam
1 @Retention(RetentionPolicy.RUNTIME) 2 @Target({ElementType.FIELD}) 3 @Documented 4 public @interface FieldParam { 5 6 /** 7 * 字段类型 默认字典 8 * Constant.FIELDTYPE_DICT 为自定义常量 9 * @return10 */11 int type() default Constant.FIELDTYPE_DICT;12 13 /**14 * 字典dictType15 * @return16 */17 String dictType() default "";18 19 /**20 * 要翻译的字段 目标字段为翻译的字段+Str21 * @return22 */23 String targetField() default "";24 25 /**26 * 要翻译的字段值类型27 * @return28 */29 Class targetFieldValueClazz() default String.class;30 31 }
二、注解的使用
在需要转义方法体上添加注解,在注解上指定需要转义的字段,不声明则使用默认值。
@TranslationDict({@FieldParam(dictType = "CUSTOMER_SEX", targetField = "sex"), @FieldParam(dictType = "CUSTOMER_STATUS", targetField = "status", targetFieldValueClazz = Integer.class)})
三、新建切面
切面核心在于将结果集转为JSON字符串,通过正则查询需要转义的字段,进行拼接替换,以增加属性。
1 @Aspect 2 @Component 3 @Slf4j 4 public class TranslateFieldAspect { 5 6 /** 7 * 翻译字典值 8 * @param joinPoint 9 * @return 10 * @throws Throwable 11 */ 12 @Around("@annotation(com.vfangtuan.vft.common.annotation.TranslationDict)") 13 public Object aroundMethodDict(ProceedingJoinPoint joinPoint) throws Throwable { 14 //接收到请求时间 15 Long startTime = System.currentTimeMillis(); 16 //注意,如果调用joinPoint.proceed()方法,则修改的参数值不会生效,必须调用joinPoint.proceed(Object[] args) 17 Object result = joinPoint.proceed(); 18 19 // 第一步、获取返回值类型 20 Class returnType = ((MethodSignature) joinPoint.getSignature()).getReturnType(); 21 22 //首先,取出要翻译字段的字典值 23 String returnJsonResult = JSONObject.toJSONString(result); 24 //开始解析(翻译字段注解参数指定的字段) 25 Method method = ((MethodSignature) joinPoint.getSignature()).getMethod(); 26 //获取注解上参数 27 TranslationDict annotation = method.getAnnotation(TranslationDict.class); 28 FieldParam[] fieldParams = annotation.value(); 29 //遍历 30 for (FieldParam fieldParam : fieldParams) { 31 log.info("开始翻译字典CODE:{},取值字段:{},取值字段值类型:{}.", 32 fieldParam.dictType(),fieldParam.targetField(),fieldParam.targetFieldValueClazz()); 33 Pattern dictPattern = getPattern(fieldParam); 34 Matcher dictMatcher=dictPattern.matcher(returnJsonResult); 35 StringBuffer sb = new StringBuffer(); 36 //转义字段 37 this.translateDict(fieldParam,dictPattern,dictMatcher,sb); 38 dictMatcher.appendTail(sb); 39 returnJsonResult = sb.toString(); 40 } 41 42 result = JSONObject.parseObject(returnJsonResult,returnType); 43 //如果这里不返回result,则目标对象实际返回值会被置为null 44 //处理完请求时间 45 Long endTime = System.currentTimeMillis(); 46 log.info("The request takes {}ms",endTime-startTime); 47 return result; 48 } 49 /** 50 * 字典值转义为中文 51 * @param fieldParam 52 * @param fieldPattern 53 * @param fieldMatcher 54 * @param sb 55 */ 56 private void translateDict(FieldParam fieldParam, Pattern fieldPattern, Matcher fieldMatcher, StringBuffer sb) { 57 //从缓存中一次性取值 58 Map<String, String> dictNames = DictData.getDictNames(fieldParam.dictType()); 59 while (fieldMatcher.find()){ 60 61 //取出要翻译字段对应的值 62 Matcher dictValueMatcher = fieldPattern.matcher(fieldMatcher.group()); 63 dictValueMatcher.find(); 64 String group = dictValueMatcher.group(); 65 //""sex":1", ""sex":"1"",""sex":null" 66 //属性无值 67 if (group.split(":").length <= 1) continue; 68 String dictName = ""; 69 70 //获取字典值 71 String dictValue = group.split(":")[1].replace("\"", ""); 72 //属性值非为空 为空赋值空串 73 if (StringUtils.isNotBlank(dictValue) && !dictValue.toLowerCase().equals("null")){ 74 //多值 75 if (dictValue.split(",").length > 1){ 76 for (String s : dictValue.split(",")) { 77 //fieldParam.dictType() + "_" + s 根据自己字典表设置的规则去查询 78 dictName += dictNames.get(fieldParam.dictType() + "_" + s) + "/"; 79 } 80 }else { 81 dictName = dictNames.get(fieldParam.dictType() + "_" + dictValue); 82 } 83 } 84 85 String s = "\"" + fieldParam.targetField() + "Str" + "\":\"" + dictName + "\"," + fieldMatcher.group(); 86 log.debug("拼接后字符串:{}",s); 87 fieldMatcher.appendReplacement(sb, s); 88 } 89 } 90 /** 91 * 获取对应的正则式 92 * @param fieldParam 93 * @return 94 */ 95 private Pattern getPattern(FieldParam fieldParam) { 96 Pattern fieldPattern;//属性整型 字符型 97 if (fieldParam.targetFieldValueClazz().equals(Integer.class) ){ 98 fieldPattern= Pattern.compile("\""+fieldParam.targetField() +"\":(\\d+)?"); 99 }else {100 fieldPattern= Pattern.compile("\""+fieldParam.targetField() +"\":\"([0-9a-zA-Z_,]+)?\"");101 }102 return fieldPattern;103 }104 }
四、测试
测试类
1 @Slf4j 2 @RestController 3 @RequestMapping("/demo") 4 @Api(tags="demo") 5 public class DemoController { 6 7 8 /** 9 * 测试注解字典10 * @return11 */12 @TranslationDict({@FieldParam(dictType = "CUSTOMER_SEX", targetField = "sex"),13 @FieldParam(dictType = "CUSTOMER_......原文转载:http://www.shaoqun.com/a/836064.html
跨境电商:https://www.ikjzd.com/
acca是什么:https://www.ikjzd.com/w/1370
adore:https://www.ikjzd.com/w/2202
王惟:https://www.ikjzd.com/w/1744
本文为解决项目中字典值的转义问题,通过注解获取结果集转为JSON字符串,再通过正则查找附加字段,完成字典值的转义。 一直以来,前端展示字典一般以中文展示为主,若在表中存字典值中文,当字典表更改字典值对应的中文,会造成数据不一致,为此设置冗余字段并非最优方案,若由前端自己写死转义,不够灵活,若在业务代码转义,臃肿也不够通用,从网络上了解到注解、AOP是一种不错的解决方案,主要有两种方式: 1、通
巴克莱银行:https://www.ikjzd.com/w/2775
宁波放大招!2019年中国跨境电商高峰论坛亮点颇多!:https://www.ikjzd.com/articles/97189
物流小知识!教你查询最新出口美国的豁免清单产品:https://www.ikjzd.com/articles/97190
海外版聚划算来袭?跨境商品测评返佣平台上线了!:https://www.ikjzd.com/articles/97191
商用餐厨在亚马逊欧洲日本的特色选品/合规要求/采购痛点:https://www.ikjzd.com/articles/97192
村长把小娥压在玉米地 又粗又大的机巴好爽:http://lady.shaoqun.com/m/a/247046.html
几个学长一起要我厕所 学长你的好大我不敢:http://lady.shaoqun.com/m/a/247930.html
口述我与同事的出轨经历细节 他的承诺像烟花一样转瞬即逝:http://www.30bags.com/m/a/250528.html
90%的人在床上都会犯的性错误:http://lady.shaoqun.com/a/391589.html
福田区公共体育场馆7月1日免费开放指南:http://www.30bags.com/a/462515.html
深圳福田区游泳馆有哪些:http://www.30bags.com/a/462516.html
2021年的Prime Day会员日表现如何?:https://www.ikjzd.com/articles/146195
No comments:
Post a Comment