如何利用AOP将对象数据字典字段code转换name输出前端展示
如何利用AOP将对象数据字典字段code转换name输出前端展示
随风所欲 发表于2年前
如何利用AOP将对象数据字典字段code转换name输出前端展示
  • 发表于 2年前
  • 阅读 90
  • 收藏 3
  • 点赞 0
  • 评论 0

腾讯云 新注册用户 域名抢购1元起>>>   

摘要: 项目使用的springboot+springMVC+springDataJpa,前期我们才用字段@OneToOne注解,前端直接obj.codeObj.codename就可以达到显示字典相应那么的效果。但是后来项目分离了系统相关模块,改有一个独立的中央集权平台负责CAS、权限、基础数据维护等功能。然后面临着@OneToOne不能用了,只有一个孤零零的String code.这样前端展示无法得到对应的codeName.所以想着利用自定义注解+AOP的方式在查询后自动根据注解里指定的code去获取中央平台相关字典数据并进行转换。
  • 首先编写自定义注解

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Dict {
	String value() default "";
}

  • 然后将注解绑在需要转换的对象字段上并指明该字段所属码表的父级code

@Dict("008")
private String countStatus;

  • 接着编写aop类设定查询方法的切入点

@Aspect
@Configuration
public class DataDictionaryHandleAOP {
	@Autowired
	//数据字典处理工具类
	private DataDictionaryUtil dataDictionaryUtil;
	//设定切入点
	@Pointcut("execution(* com.bjhy.platform.sw.*.service.impl.*.findByPage(..)) || execution(* com.bjhy.platform.sw.*.service.impl.*.findByPage_*(..))")
	private void anyMethod(){};
	
	//切入方式为后切入
	@AfterReturning("anyMethod() && args(pageInfo)")
	public void doAfter(PageInfo<?> pageInfo){
		System.out.println("AOP数组字典code转name--start "+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
		int count = 0;
		//获取数据集
		List<?> list = pageInfo.getPage().getContent();
		if(list!=null&&list.size()>0){
			long startD = new Date().getTime();
			//初始中央平台获取class转换所需的码表集合
			dataDictionaryUtil.initData(list.get(0).getClass());
			//开始转换
			dataDictionaryUtil.handDictionaryCodeToCodeName(list);
			count  = (int) (new Date().getTime() - startD);
		}
		System.out.println("AOP数组字典code转name--end"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
		System.out.println("耗时:"+count+" ms");
	}
	
}

  • 最后通过反射编写转换代码,特别处理部分@OneToOne链表对象

@Component
public class DataDictionaryUtil {
	@Reference
	private SystemCodeService systemCodeService;//cas系统获取数据字典服务
	@Reference
	private OrganizationService organizationService;//cas系统获取组织机构服务
	//数据字典
	private static List<SystemCode> dictList = new ArrayList<SystemCode>();
	//组织机构字典
	private static List<OrganizationInfo> orgList = new ArrayList<OrganizationInfo>();
	//需要转化的字段名
	private static String fieldNames = "";
	//已经获取的数据字典记录,避免重复去cas系统获取
	private static Map<String, String> codeRecord = new HashMap<String, String>();
	
	/**
	 * 根据clzz初始将要转化的字典数据
	 * @param clzz 需要转换的对象class
	 */
	public <T> void initData(Class<T> clzz){
		clear();
		initDictionary(clzz);
	}
	
	public void clear(){
		fieldNames = "";
	}
	
	public <T> void initDictionary(Class<T> clzz){
		Field[] fields = clzz.getDeclaredFields();
		for (Field field : fields) {
			Class c = field.getType();
			//判断字段否是对象
			if(null!=c.getClassLoader()){
				//递归获取需要转换的字段
				initDictionary(c);
			}else{
				if(field.isAnnotationPresent(Dict.class)){
					fieldNames += clzz.getSimpleName()+"."+field.getName()+",";
					Dict dict = field.getAnnotation(Dict.class);
					//判断是否已经获取过该code的字典数据 避免重复获取
					if(codeRecord.get(dict.value()) == null){
						List<SystemCode> list = systemCodeService.getChildrenByCode(dict.value());
						if(list!=null&&list.size()>0){
							dictList.addAll(list); 
							//记录已经获取的字典code
							codeRecord.put(dict.value(), dict.value());
						}
					}
				}else if(field.isAnnotationPresent(Org.class)){
					fieldNames += clzz.getSimpleName()+"."+field.getName()+",";
					Org org = field.getAnnotation(Org.class);
					if(codeRecord.get(org.value()) == null){
						List<OrganizationInfo> list = organizationService.getChildrenByType(org.value());
						if(list!=null&&list.size()>0){
							orgList.addAll(list);
							codeRecord.put(org.value(), org.value());
						}
					}
				}
			}
		}
	}
	/**
	 * 将指定数据内凡是对象标注有@dict @org 注解的字段转化为对应数据字典的codeName)
	 * @param datalist 数据集合(一般为分页查询后的pageInfo.getPage().getContent()数据)
	 * @return 返回List<Object> 
	 */
	public <T> List<Object> handDictionaryCodeToCodeName(List<?> datalist){
		System.out.println("需要转换的字段为:"+fieldNames);
		if(StringUtils.isNotEmpty(fieldNames)){
			String[] fNames = fieldNames.split(",");
			for (Object object : datalist) {
				codeToName(fNames, object);
			}
		}
		return (List<Object>) datalist;
	}
	
	public void codeToName(String[] fNames,Object object){
		String classFieldName = "";
		Class clzz = object.getClass();
		Field[] fields = clzz.getDeclaredFields();
		for (int i = 0; i < fNames.length; i++) {
			for (Field field : fields) {
				Class c = field.getType();
				//是否是对象
				if(null!=c.getClassLoader()){
					//只统计一次
					if(i==0){
						classFieldName += field.getName()+",";
					}
				}else{
					String[] n = fNames[i].split("\\.");
					if(clzz.getSimpleName().equals(n[0])&&field.getName().equals(n[1])){
//						System.out.println("开始转换字段:"+fNames[i]);
						try {
							field.setAccessible(true);
							String val = (String) field.get(object);
							if(field.isAnnotationPresent(Dict.class)){
								for (SystemCode code : dictList) {
									if(code.getCode().equals(val)){
										field.set(object, code.getCodeName());
										break;
									}
								}
							}else if(field.isAnnotationPresent(Org.class)){
								for (OrganizationInfo org : orgList) {
									if(org.getOrgCode().equals(val)){
										field.set(object, org.getOrgName());
										break;
									}
								}
							}
						} catch (Exception e) {
							e.printStackTrace();
						}
						break;
					}
				}
			}
		}
		String[] classFieldNames = classFieldName.split(",");
		for (String fieldName : classFieldNames) {
			try {
				if(StringUtils.isNotEmpty(fieldName)){
					Field classField = clzz.getDeclaredField(fieldName);
					classField.setAccessible(true);
					if(null!=classField.get(object)){
						codeToName(fNames, classField.get(object));
					}
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
	
	public static void main(String[] args) {
		
	}

}


共有 人打赏支持
粉丝 2
博文 9
码字总数 7237
×
随风所欲
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: