字段翻译
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 ![在这里插入图片描述](https://img-blog.csdnimg.cn/e9160d1744a14b5fac311273913b2e13.png)
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里面取值。——约定大于配置,配置大于代码代码是一面,思想是另一面。
|