springboot+redis+切面实现数据字典功能

自定义注解:DataDict,用于bo对象类,需要翻译的属性

 

package com.zddts.common.annotation.dict;

import java.lang.annotation.*;

/**
* 说明:数据字典处理类
* Created by luojie on 2019/05/29.
*/
//@DataDict( dict="patType", source = "patType" )
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DataDict {


/**
* 方法描述 描述标准编码
* @return
*/
String dict() default "";

/**
* 方法描述,可使用占位符获取参数:{{source}}
* 主要标准编码之来源
*/
String source() default "";


}
 

自定义注解: 

DataDictClass 用来表面返回对象集合需要,本功能目前只支持bean对象的属性翻译
 

package com.zddts.common.annotation.dict;

import java.lang.annotation.*;

/**
* 说明:
* Created by luojie on 2019/05/29.
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DataDictClass {

}
切面处理: DataDictAspect

package com.zddts.ac.aop;

import com.alibaba.fastjson.JSON;
import com.zddts.ac.client.PubappClient;
import com.zddts.common.annotation.dict.DataDict;
import com.zddts.common.annotation.dict.DataDictClass;
import com.zddts.common.bo.pubapp.PuCodeBo;
import com.zddts.common.utils.BeanUtils;
import org.apache.commons.lang.StringUtils;
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.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;


/**
* 说明:数据字典切面类
* Created by luojie on 2019/05/29.
*/
@Aspect
@Component
public class DataDictAspect {

@Autowired
PubappClient pubappClient;

/**
* 非基本类型在 CLASS 中的定义
*/
private static final String FILED_NAME_TYPE = "TYPE";

private Map<String, String> dictInfoMap = new ConcurrentHashMap<>();

@Pointcut("@annotation(dataDictClass)")
public void doDataDictClass(DataDictClass dataDictClass) {
}

@Around("@annotation(dataDictClass)")
public Object translation(final ProceedingJoinPoint pjp, DataDictClass dataDictClass) throws Throwable {
Object result = pjp.proceed();
if (result == null) {
return result;
}
Object obj;
if (result instanceof List || result instanceof ArrayList) {
List olist = ((List) result);
if (olist.size() == 0) {
return result;
}
obj = olist.get(0);
} else {
obj = result;
}
List<Map<String, String>> dictParams = boDict(obj.getClass());
if (dictParams.size() == 0) {
return result;
}
//TODO 后期需优化读取Redis
List<PuCodeBo> dictInfos = pubappClient.getPuCodeByType("patType");

if (dictInfos == null && dictInfos.size() == 0) {
return result;
}
//先把字典值转成map
for (PuCodeBo puCodeBo : dictInfos) {
dictInfoMap.put(puCodeBo.getCodeType() + puCodeBo.getValue(), puCodeBo.getCodeName());
}

if (result instanceof List || result instanceof ArrayList) {
for (Object o : (List) result) {
sign(o, dictParams, dictInfoMap);
}
} else {
sign(result, dictParams, dictInfoMap);
}
return result;
}

/**
* 单个设置值
*
* @param obj
* @param dictParams
* @param dictInfoMap
*/
public void sign(Object obj, List<Map<String, String>> dictParams, Map<String, String> dictInfoMap) {

for (Map<String, String> dictParam : dictParams) {
String dict = dictParam.get("dict");
String source = dictParam.get("source");
String dictName = dictParam.get("dictName");
try {
//获取源编码值
String sourceValue = (String) BeanUtils.getBeanFieldValue(obj.getClass(), obj, source);
String dictCodeName = dictInfoMap.get(dict + sourceValue);
//设置值
BeanUtils.setBeanField(obj.getClass(), obj, dictName, dictCodeName);
} catch (Exception e) {
e.printStackTrace();
}

}


}

/**
* 获取bo中属性值
*
* @param cla
* @return
*/
private List<Map<String, String>> boDict(Class cla) {
Field[] fields = cla.getDeclaredFields();
List<Map<String, String>> list = new ArrayList<Map<String, String>>();
Map<String, String> map;
DataDict dataDict;
for (Field field : fields) {
if (field.isAnnotationPresent(DataDict.class)) {
map = new HashMap<String, String>();
dataDict = field.getAnnotation(DataDict.class);
map.put("dict", dataDict.dict());
map.put("source", dataDict.source());
map.put("dictName", field.getName());
list.add(map);
}
}
return list;
}





}
使用:

 对要数据字典转换的方法加上DataDictClass注解

 

需要注解翻译的加上注解DataDict ,dict是指标准码的编码

 

工具类:主要用了反射机制

package com.zddts.common.utils;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.*;
import java.util.Map.Entry;

public class BeanUtils {

/**
* 方法说明:将List<Map>转换为List<Bean>
*
* @param mapList
* @param cls
* @return
* @throws Exception
*/
public static List<Object> mapListToBeanList(
List<Map<String, Object>> mapList, Class<?> cls) throws Exception {
if (mapList == null || mapList.size() == 0) {
return null;
}
List<Object> beanList = new ArrayList<Object>();
Object bean = null;
for (Map<String, Object> map : mapList) {
bean = mapToBean(map, cls);
if (bean == null) {
continue;
}
beanList.add(bean);
}
return beanList;
}

/**
* 设置bean 属性值,没有下划线的
*
* @param map
* @param cls
* @return
* @throws Exception
*/
public static Object mapToBeanNL(Map<String, Object> map, Class<?> cls) throws Exception {
if (map == null || map.size() == 0) {
return null;
}
Object obj = cls.newInstance();
for (Entry<String, Object> entry : map.entrySet()) {
String key = entry.getKey();
Object value = entry.getValue();
if (value == null) {
continue;
}
// 判断字段是否存在
String fieldName = key;
Field field = getBeanField(cls, fieldName);
if (field == null) {
continue;
}
// 判断字段的set方法是否存在
String setMethodName = StringUtils.pareSetName(fieldName);
Method method = getBeanMethod(cls, setMethodName, field.getType());
if (method == null) {
continue;
}

String fieldType = field.getType().getSimpleName();
if ("String".equals(fieldType)) {
method.invoke(obj, value.toString());
} else if ("long".equals(fieldType) || "Long".equals(fieldType)) {
method.invoke(obj, Long.valueOf(value.toString()));
} else if ("int".equals(fieldType) || "Integer".equals(fieldType)) {
method.invoke(obj, value.toString());
} else if ("double".equals(fieldType) || "Double".equals(fieldType)) {
method.invoke(obj, Double.valueOf(value.toString()));
} else if ("float".equals(fieldType) || "Float".equals(fieldType)) {
method.invoke(obj, Float.valueOf(value.toString()));
} else if ("boolean".equals(fieldType) || "Boolean".equals(fieldType)) {
if (value.getClass().equals(Boolean.class)) {
method.invoke(obj, (Boolean) value);
} else {
method.invoke(obj, Boolean.valueOf(value.toString()));
}
} else if ("Date".equals(fieldType)) {
if (value != null) {
if (value.getClass().equals(Date.class)) {
method.invoke(obj, (Date) value);
} else {
method.invoke(obj, DateUtils.strToDate(value.toString()));
}
}
}
}
return obj;
}

/**
* 设置bean 属性值
*
* @param map
* @param cls
* @return
* @throws Exception
*/
public static Object mapToBean(Map<String, Object> map, Class<?> cls)
throws Exception {
if (map == null || map.size() == 0) {
return null;
}
Object obj = cls.newInstance();
for (Entry<String, Object> entry : map.entrySet()) {
String key = entry.getKey();
Object value = entry.getValue();
if (value == null) {
continue;
}
// 判断字段是否存在
String fieldName = StringUtils.toUnderLine(key.toLowerCase());
Field field = getBeanField(cls, fieldName);
if (field == null) {
continue;
}
// 判断字段的set方法是否存在
String setMethodName = StringUtils.pareSetName(fieldName);
Method method = getBeanMethod(cls, setMethodName, field.getType());
if (method == null) {
continue;
}

String fieldType = field.getType().getSimpleName();
if ("String".equals(fieldType)) {
method.invoke(obj, value.toString());
} else if ("long".equals(fieldType) || "Long".equals(fieldType)) {
method.invoke(obj, Long.valueOf(value.toString()));
} else if ("int".equals(fieldType) || "Integer".equals(fieldType)) {
method.invoke(obj, value.toString());
} else if ("double".equals(fieldType) || "Double".equals(fieldType)) {
method.invoke(obj, Double.valueOf(value.toString()));
} else if ("float".equals(fieldType) || "Float".equals(fieldType)) {
method.invoke(obj, Float.valueOf(value.toString()));
} else if ("boolean".equals(fieldType)
|| "Boolean".equals(fieldType)) {
if (value.getClass().equals(Boolean.class)) {
method.invoke(obj, (Boolean) value);
} else {
method.invoke(obj, Boolean.valueOf(value.toString()));
}
} else if ("Date".equals(fieldType)) {
if (value != null) {
if (value.getClass().equals(Date.class)) {
method.invoke(obj, (Date) value);
} else {
method.invoke(obj, DateUtils
.strToDate(value.toString()));
}
}
}
}
return obj;
}

/**
* 方法说明:将List<Bean>转换为List<Map>
*
* @param beanList
* @return
* @throws Exception
*/
public static List<Map<String, Object>> beanListToMapList(
List<Map<String, Object>> beanList) throws Exception {
if (beanList == null || beanList.size() == 0) {
return null;
}
List<Map<String, Object>> mapList = new ArrayList<Map<String, Object>>();
Map<String, Object> map = null;
for (Object bean : beanList) {
map = beanToMap(bean);
if (map == null || map.size() == 0) {
continue;
}
mapList.add(map);
}
return mapList;
}

/**
* 设置bean 属性值
*
* @param bean
* @return
* @throws Exception
*/
public static Map<String, Object> beanToMap(Object bean) throws Exception {
if (bean == null) {
return null;
}
Map<String, Object> map = new HashMap<String, Object>();
Class<?> cls = bean.getClass();
Field fields[] = cls.getDeclaredFields();
for (Field field : fields) {
String fieldName = field.getName();
String fieldType = field.getType().getSimpleName();
boolean isBooleanType = false;
if (fieldType.equals("boolean") || fieldType.equals("Boolean")) {
isBooleanType = true;
}
String getMethodName = StringUtils.pareGetName(fieldName,
isBooleanType);
// 判断字段的无参get方法是否存在
Method method = getBeanMethod(cls, getMethodName, new Class[]{});
if (method == null) {
continue;
}
Object fieldValue = method.invoke(bean, new Object[]{});
map.put(StringUtils.toUnderLine(field.getName()).toUpperCase(),
fieldValue);
}
return map;
}

/**
* 判断该方法是否存在
*
* @param methods
* @param met
* @return
*/
public static boolean checkMethod(Method methods[], String met) {
if (null != methods) {
for (Method method : methods) {
if (met.equals(method.getName())) {
return true;
}
}
}
return false;
}

/**
* 方法说明:获取bean的指定方法
* <p>
* <p>
* Author: zhenqiangs Create Date: 2016-4-30 下午01:07:12 History: 2016-4-30
* 下午01:07:12 zhenqiangs Created.
*
* @param cls
* @param methodName
* @param paramTypes
* @return
*/
private static Method getBeanMethod(Class<?> cls, String methodName,
Class<?>... paramTypes) {
if (cls == null) {
return null;
}
Method setMethod = null;
try {
setMethod = cls.getMethod(methodName, paramTypes);
} catch (Exception e) {

}
return setMethod;
}

/**
* 方法说明:获取bean的指定属性
*
* @param cls
* @param fieldName
* @return
*/
public static Field getBeanField(Class<?> cls, String fieldName) {
if (cls == null) {
return null;
}
Field field = null;
try {
field = cls.getDeclaredField(fieldName);
} catch (Exception e) {

}
return field;
}

/**
* 设置对应值
*
* @param fieldName
*/
public static void setBeanField(Class<?> cls, Object obj, String fieldName, Object value) throws Exception {

// 判断字段是否存在
Field field = getBeanField(cls, fieldName);
if (field == null) {
return;
}
// 判断字段的set方法是否存在
String setMethodName = StringUtils.pareSetName(fieldName);
Method method = getBeanMethod(cls, setMethodName, field.getType());
if (method == null) {
return;
}
//为空不设置
if (value == null) {
return;
}
String fieldType = field.getType().getSimpleName();
if ("String".equals(fieldType)) {
method.invoke(obj, value.toString());
} else if ("long".equals(fieldType) || "Long".equals(fieldType)) {
method.invoke(obj, Long.valueOf(value.toString()));
} else if ("int".equals(fieldType) || "Integer".equals(fieldType)) {
method.invoke(obj, value.toString());
} else if ("double".equals(fieldType) || "Double".equals(fieldType)) {
method.invoke(obj, Double.valueOf(value.toString()));
} else if ("float".equals(fieldType) || "Float".equals(fieldType)) {
method.invoke(obj, Float.valueOf(value.toString()));
} else if ("boolean".equals(fieldType) || "Boolean".equals(fieldType)) {
if (value.getClass().equals(Boolean.class)) {
method.invoke(obj, (Boolean) value);
} else {
method.invoke(obj, Boolean.valueOf(value.toString()));
}
} else if ("Date".equals(fieldType)) {
if (value.getClass().equals(Date.class)) {
method.invoke(obj, (Date) value);
} else {
method.invoke(obj, DateUtils.strToDate(value.toString()));
}
}
}

/**
* 设置对应值
*
* @param fieldName
*/
public static Object getBeanFieldValue(Class<?> cls, Object obj, String fieldName) throws Exception {

// 判断字段是否存在
Field field = getBeanField(cls, fieldName);
// 判断字段的set方法是否存在
String getMethodName = StringUtils.pareGetName(fieldName, false);
// 判断字段的无参get方法是否存在
Method method = getBeanMethod(cls, getMethodName, new Class[]{});
Object fieldValue = method.invoke(obj, new Object[]{});
return fieldValue;
}
}
 

 

 source 指bean中翻译所需要对应的值字段
---------------------

posted @ 2019-07-17 05:03  李艳艳665  阅读(4650)  评论(1编辑  收藏  举报