zoukankan      html  css  js  c++  java
  • Spring Aop 修改目标方法参数和返回值

    一、新建注解

    @Target({ElementType.METHOD, ElementType.TYPE})  
    @Retention(RetentionPolicy.RUNTIME)  
    @Documented  
    @Mapping 
    public @interface HandleField {
    
        //方法参数加密字段(顺序与方法参数顺序一致;字段类型为string)
        public String[] encrypFieldNameInfo();
    
        //解密方法返回值字段(支持 map的key domain 和list<domain>) 字段类型为string
        public String decrypResultFieldName() default "";
    
    }

    二、建立切面

    @Component("changeIdNoAopHandler")
    public class ChangeIdNoAopHandler {
    
        private static Logger logger = LoggerFactory.getLogger(ChangeIdNoAopHandler.class);
    
        private static final String SECRET_KEY = "12345678"; //秘钥
    
        private String HANDLE_FIELD_NAME = "idNo"; //加密解密字段
    
        private static final String ENCRYPT_FLAG = "encrypt"; //加密标识 (判断对值进行加密或者解密的操作)
    
        private static final String DECRYPT_FLAG = "decrypt"; //解密标识(判断对值进行加密或者解密的操作)
    
        @Autowired
        private InetxValDualService netxValDualService;
    
        @Autowired
        private IThemisCryptoIdnoService themisCryptoIdnoService;
        /***
         * 
         * @Description(功能描述)    :  切面方法 (修改目标方法参数中带有 idNo字段的值;修改目标方法返回值带有idNo的字段)
         * @author(作者)             :  
         * @date (开发日期)          :  2017-9-13 下午5:30:24 
         * @exception                : 
         * @param joinPoint
         * @return
         * @throws Throwable  Object
         */
        public Object parameterCheck(ProceedingJoinPoint joinPoint) throws Throwable{
            logger.info("开始执行aop方法修改参数。。。");
            Object target = joinPoint.getTarget();//返回被织入增强处理的目标对象       getThis:返回AOP框架为目标对象生成的代理对象
            Object[] args = joinPoint.getArgs(); //获取目标对象方法参数
            //遍历参数 修改带有idNo字段对象的值 (map list<domain> domain)
            for (Object _obj : args) {
                try{
                    changValue(_obj,ENCRYPT_FLAG); //加密参数
                }catch (Exception e) {  //使用异常机制来验证 _obj中 是否有idNo 字段
                    logger.error("修改目标方法参数字段值异常。目标类:"
                            +target.getClass()+"方法:"+joinPoint.getSignature().getName()+"修改的值:"+_obj,e);
                }
            }
            //执行方法,以新的参数(如果不带args就是用原先的参数;这里带不带都可以是,上面方法获取原先参数的引用做的修改)
            Object returnValue = joinPoint.proceed(args); 
            //若未设置,则不需要解密
            if(!ObjectIsNullUtil.isNullOrEmpty(returnValue)){
                try{
                    //修改
                    returnValue = changValue(returnValue,DECRYPT_FLAG); //解密参数
                }catch (Exception e) {  //使用异常机制来验证 _obj中 是否有idNo 字段
                    logger.error("修改目标方法返回值异常。目标类:"
                            +target.getClass()+"方法:"+joinPoint.getSignature().getName()+"修改的值:"+returnValue,e);
                }
            }
            return returnValue;  
        }  
        /***
         * 
         * @Description(功能描述)    :  修改对象idNo字段的值
         * @author(作者)             :  
         * @date (开发日期)          :  2017-9-13 下午5:30:07 
         * @exception                : 
         * @param _obj
         * @param flag     加密解密字段
         * @throws Exception  void
         */
        private Object changValue(Object _obj, String flag) throws Exception{
            //基本类型不作操作
            if(_obj instanceof Map){
                changeMapValue(_obj,flag);
            }else if(_obj instanceof List){
                @SuppressWarnings("unchecked")
                List<Object> list = (List<Object>) _obj;
                for (Object obj : list) {
                    if(obj instanceof Map){
                        changeMapValue(_obj,flag);
                    }else{
                        changObjectValue(_obj,flag);
                    }
                }
            }else{
                changObjectValue(_obj,flag);
            }
            return _obj;
        }
        /**
         * 
         * @Description(功能描述)    :  当对象为Map 修改key的值
         * @author(作者)             :  吴桂镇
         * @date (开发日期)          :  2017-9-14 上午11:17:50 
         * @exception                : 
         * @param _obj
         * @param flag 
         * @return  Object
         * @throws Exception 
         */
        @SuppressWarnings("unchecked")
        private Object changeMapValue(Object _obj, String flag) throws Exception{
            Map<String,Object> map = (Map<String,Object>) _obj;
            if(map.containsKey(HANDLE_FIELD_NAME)){
                Object fieldValue = map.get(HANDLE_FIELD_NAME);
                String afterValue = crypto(fieldValue, flag);
                if(!ObjectIsNullUtil.isNullOrEmpty(afterValue)){
                    map.put(HANDLE_FIELD_NAME, afterValue);
                }
            }
            return _obj;
        }
    
        /***
         * 
         * @Description(功能描述)    :  修改Object对象field的值
         * @author(作者)             :  
         * @date (开发日期)          :  2017-9-14 上午11:37:07 
         * @exception                : 
         * @param _obj
         * @param flag
         * @return
         * @throws Exception  Object
         */
        private Object changObjectValue(Object _obj, String flag) throws Exception{
            Class<?> resultClz = _obj.getClass();
            Field[] fieldInfo = resultClz.getDeclaredFields(); //获取class里的所有字段  父类字段获取不到    注:如果出现加密解密失败 请先查看idno是否在父类中
            for (Field field : fieldInfo) {
                if(HANDLE_FIELD_NAME.equals(field.getName())){
                    field.setAccessible(true); //成员变量为private,故必须进行此操
                    Object fieldValue = field.get(_obj);
                    String afterValue = crypto(fieldValue, flag);
                    if(!ObjectIsNullUtil.isNullOrEmpty(afterValue)){
                        field.set(_obj, afterValue);
                    }
                    break;
                }
            }
            return _obj;
        }
    
        /***
         * 
         * @Description(功能描述)    :  加密操作
         * @author(作者)             : 
         * @date (开发日期)          :  2017-9-14 下午3:20:32 
         * @exception                : 
         * @param value
         * @param flag
         * @return  String
         * @throws Exception 
         */
        private String crypto(Object value,String flag) throws Exception{
            if(ObjectIsNullUtil.isNullOrEmpty(value)){
                return null;
            }
            //加密操作;加密之前先去查询一下数据库 有没有 如果没有 则insert
            if (ENCRYPT_FLAG.equals(flag)) { 
                String encodeValue = Encryption.encode(SECRET_KEY, value.toString()); //加密
                ThemisCryptoIdno idnoDomain = new ThemisCryptoIdno();
                idnoDomain.setCryptoIdno(encodeValue);
                idnoDomain = themisCryptoIdnoService.selectOneByObject(idnoDomain);
                if(ObjectIsNullUtil.isNullOrEmpty(idnoDomain)){ //若空 则生成 seq 然后入库  返回seq
                    String tr_date = DateOperation.convertToDateStr2(DateOperation.currentTimeMills());
                    //获取有流水号
                    String inextValDual=netxValDualService.findIdNoSeq();
                    //组流水:日期+ 7位流水   其他表储存的就是这个idnoSeq
                    String idnoSeq=(tr_date+DateOperation.fill(inextValDual, '0', 7, true)).replaceAll("-", ""); 
                    idnoDomain = new ThemisCryptoIdno();
                    idnoDomain.setOptTime(DateOperation.convertToDateStr1(DateOperation.currentTimeMills()));
                    idnoDomain.setCryptoIdno(encodeValue);
                    idnoDomain.setCryptoSeq(idnoSeq);
                    themisCryptoIdnoService.insert(idnoDomain);
                    return idnoSeq;
                }else{ //不为空 直接返回seq
                    return idnoDomain.getCryptoSeq();
                }
            }else{ //解密操作 通过seq 查询 然后解密返回明文
                ThemisCryptoIdno idnoDomain = new ThemisCryptoIdno();
                idnoDomain.setCryptoSeq(value.toString());
                idnoDomain = themisCryptoIdnoService.selectOneByObject(idnoDomain);
                if(!ObjectIsNullUtil.isNullOrEmpty(idnoDomain)){
                    return Encryption.decodeValue(SECRET_KEY, idnoDomain.getCryptoIdno()); //解密
                }
            }
            return null;
        }
    
        public static void main(String[] args) throws Exception {
            System.out.println(Encryption.encode(SECRET_KEY, "142701197605091275"));
        }
    }

    三、注解使用

    @Component
    public class SusrService implements ISusrService{
    
        @Autowired
        private SusrDao susrDao;
    
        @Override
        @HandleField(encrypFieldNameInfo={"usrCde"},decrypResultFieldName="usrCde")
        public sUsr selectOneByObject(sUsr su) {
            return susrDao.selectOneByObject(su);
        }
    }
  • 相关阅读:
    积累学习
    华为手机 android8.0APP更新时出现安装包解析异常的提示及安装闪退(无反应)问题
    新建Application 报错android.app.Application cannot be cast
    Android Studio Gradle无法获取pom文件
    取消设置透明状态栏,使 ContentView 内容不再覆盖状态栏
    Android欢迎页短暂白屏
    android Toast提示异常:java.lang.RuntimeException: Can't create handler inside thread that has not called
    ransformResourcesWithMergeJavaResForDebug问题
    android studio toolbar遮挡住下面控件内容
    Android VideoView无法播放网络视频
  • 原文地址:https://www.cnblogs.com/azhqiang/p/10231507.html
Copyright © 2011-2022 走看看