注解五:字段翻译(注解+反射+动态属性)

您所在的位置:网站首页 prescription翻译成中文 注解五:字段翻译(注解+反射+动态属性)

注解五:字段翻译(注解+反射+动态属性)

2024-07-10 03:52| 来源: 网络整理| 查看: 265

字段翻译 0、需求1、POM2、entity、controller、service、dao、mapper2.1、entity2.2、controller2.3、service2.4、dao2.5、mapper 3、render(注解、接口、实现类)3.1、注解@TestAnnotation3.2、接口ValueRenderer3.3、RegionRender3.4、GenderRenderer 4、aspect5、utils5.1、RenderUtil5.2、ReflectUtil 6、总结

0、需求

实现字段的自动翻译功能,例如sex=1表示男,region="1"表示国外。 在发送请求之后,将原本的字段和翻译字段都返回给前端。

例如:存在实体Payment,属性只包括(id、serial、region、sex) 调用接口时,自动返回如下内容,sexMeaning 和 regionMeaning 在这里插入图片描述

1、POM

其他POM如:jdbc、web、boot不列出来

commons-beanutils commons-beanutils 1.9.3 cglib cglib-nodep 3.2.4 com.alibaba fastjson 1.2.47 2、entity、controller、service、dao、mapper 2.1、entity public class Payment implements Serializable { private Long id; private String serial; @TestAnnotation(renderers = RegionRender.class) private String region="1"; @TestAnnotation(renderers = GenderRenderer.class) private Integer sex=1; public Integer getSex() { return sex; } public void setSex(Integer sex) { this.sex = sex; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getSerial() { return serial; } public void setSerial(String serial) { this.serial = serial; } public String getRegion() { return region; } public void setRegion(String region) { this.region = region; } @Override public String toString() { return JSON.toJSONString(this); } } 2.2、controller @RestController public class PaymentController{ @Resource private PaymentService paymentService; @PostMapping(value = "/payment/create") public Payment create(@RequestBody Payment payment) { return paymentService.create(payment); } } 2.3、service public interface PaymentService { Payment create(Payment payment); } @Service public class PaymentServiceImpl implements PaymentService { @Resource private PaymentDao paymentDao; @Override public Payment create(Payment payment) { paymentDao.create(payment); // payment.setSex(0); return payment; } } 2.4、dao @Mapper public interface PaymentDao { int create(Payment payment); } 2.5、mapper DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" > insert into payment(serial) values(#{serial}); 3、render(注解、接口、实现类) 3.1、注解@TestAnnotation @Target({ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface TestAnnotation { Class[] renderers() default {}; } 3.2、接口ValueRenderer public interface ValueRenderer { Object render(Object value, Object data); } 3.3、RegionRender public class RegionRender implements ValueRenderer { @Override public Object render(Object value, Object data) { if (value instanceof String) { String flag = (String) value; if ("0".equals(flag)) { return "国内"; } return "国外"; } return value; } } 3.4、GenderRenderer public class GenderRenderer implements ValueRenderer { @Override public Object render(Object value, Object data) { if (value instanceof Integer) { Integer longTermFlag = (Integer) value; if (Integer.valueOf(1).equals(longTermFlag)) { return "男"; } return "女"; } return value; } } 4、aspect @Aspect @Component public class PaymentAspect { private static final Logger logger = LoggerFactory.getLogger(PaymentAspect.class); @Around( value = "execution(* com.zhb.service.impl.PaymentServiceImpl.create(..))" ) @SuppressWarnings({"unchecked"}) public Object userInsert(ProceedingJoinPoint joinPoint) { Object render=null; try { Object result= joinPoint.proceed(); logger.info("调用" + joinPoint.getTarget() + "的" + joinPoint.getSignature().getName() + "方法。方法返回值:" + result); render = RenderUtil.render(result); } catch (Throwable e) { logger.error(joinPoint.getSignature().getName() + "方法发生异常:" + e); }finally { logger.info(joinPoint.getSignature().getName() + "方法结束执行。"); } return render; } } 5、utils 5.1、RenderUtil public class RenderUtil { public static Object render(Object object) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException, InstantiationException { Class clazz = object.getClass(); Field[] fields = clazz.getDeclaredFields(); String s = null; Map addProperties = new HashMap(); Object target=null; for(int i=0;i { try { // filter extra properties if (!addProperties.containsKey(k)) { dynamicBean.setValue(k, propertyUtilsBean.getNestedProperty(dest, k)); } } catch (Exception e) { logger.error(e.getMessage(), e); } }); // add extra value addProperties.forEach((k, v) -> { try { dynamicBean.setValue(k, v); } catch (Exception e) { logger.error(e.getMessage(), e); } }); Object target = dynamicBean.getTarget(); return target; } public static class DynamicBean { /** * 目标对象 */ private Object target; /** * 属性集合 */ private BeanMap beanMap; public DynamicBean(Class superclass, Map propertyMap) { this.target = generateBean(superclass, propertyMap); this.beanMap = BeanMap.create(this.target); } /** * bean 添加属性和值 * * @param property * @param value */ public void setValue(String property, Object value) { beanMap.put(property, value); } /** * 获取属性值 * * @param property * @return */ public Object getValue(String property) { return beanMap.get(property); } /** * 获取对象 * * @return */ public Object getTarget() { return this.target; } /** * 根据属性生成对象 * * @param superclass * @param propertyMap * @return */ private Object generateBean(Class superclass, Map propertyMap) { BeanGenerator generator = new BeanGenerator(); if (null != superclass) { generator.setSuperclass(superclass); } BeanGenerator.addProperties(generator, propertyMap); return generator.create(); } } } 6、总结 @Around(处理入口),render(翻译值),ReflectUtil(生成新字段)实际开发中不需要每次都进行render实现类的配置,可以做成配置项,从redis里面取值。——约定大于配置,配置大于代码代码是一面,思想是另一面。


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3