spring Aop 实现对http请求参数的验证,及对功能权限的验证

Aop 面向切面编程,在java 中普遍使用动态代理和反射实现。具体的请百度。spring aop有多种方式。本次使用的是注解方式,(建议使用注解方式)。

第一步自定义了2个注解

@Target(value={ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Verify {

}

public @interface FieldVerify {

    boolean required() default true;
    
    /***
     * 数据类型primary 基本数据
     * creator mingqiang_zhou
     * createdate 2016-6-16
     * modifyor 
     * @return
     */
    String type() default "primary";    
}
 

第二步、建立AOP实现类,和spring IOC 配合使用

@Aspect
public class FunctionRightAop {
    private static Logger logger = Logger.getLogger(FunctionRightAop.class);
       
    @Around("@annotation(com.xxx.xxx.FunctionRight)")
    public Object process(ProceedingJoinPoint joinPoint) throws Throwable{
        Object[] args = joinPoint.getArgs();
        Method method = ((MethodSignature)joinPoint.getSignature()).getMethod();

        Class<?>[] ptypes = method.getParameterTypes();
        User loginUser = null;
        int len = ptypes.length;
        for(int i = 0;i< len;i++){
            if(ptypes[i].isAssignableFrom(User.class)){
                loginUser = (User)args[i];
                break;
            }
        }
        
        String chktype = method.getAnnotation(FunctionRight.class).value();
        boolean addAble = true;

........      
        Opportunity opportunity = null;
        if(RightConstant.ACT_ADD.equals(chktype)){
            //检查添加权限
        }else{
            //需要数据进行验证权限

           。。。。
            addAble = checkAll(。。。chktype);
        }
        
        if(!addAble){
            throw new AuthException(AppCodeEnum.no_right.getCode(),AppCodeEnum.no_right.getMsg());
        }else if(!RightConstant.ACT_ADD.equals(chktype)){
            //设置获取的对象,节省再次请求数据库
            args[len-1] = new Opportunity[]{opportunity};
        }
        
        Object returnValue = joinPoint.proceed(args);
        
        return returnValue;
    }

可以看到如果在权限验证中使用了,要获取的数据,可以直接将数据当做参数传递到被调用方法中,当然在被调用方法需要定义好参数。

 

第三步、 在Aop代理中根据注解不能内容进行参数验证。

private boolean procee(Object obj){
        if(obj == null){
            return false;
        }else if(obj instanceof String&&StringUtils.isBlank((String)obj)){
            return false;
        }else if(obj instanceof List){
            List<?> objs = (List<?>)obj;
            if(objs==null||objs.isEmpty()){
                return false;
            }
        }else if(obj instanceof Map<?, ?>){
            Map<?, ?> map = (Map<?, ?>)obj;
            if(map==null||map.isEmpty()){
                return false;
            }
        }else{
            Class<?> pclass = obj.getClass();
            if(pclass.getAnnotation(Verify.class)!=null){
                Field[] fields = pclass.getDeclaredFields();
                if(fields!=null){
                    for(Field field : fields){
                        if(field.getAnnotation(FieldVerify.class)!=null){
                            field.setAccessible(true);
                            try {
                                Object propertyObj = field.get(obj);
                                boolean re = procee(propertyObj);
                                if(!re){
                                    return re;
                                }
                            } catch (IllegalArgumentException e) {
                                logger.error(e.getMessage(),e);
                                return false;
                            } catch (IllegalAccessException e) {
                                logger.error(e.getMessage(),e);
                                return false;
                            }
                        }
                    }
                }
            }
        }
        return true;
    }

这个解析是十分简单的验证十分有数据,没有对数据的具体内容进行解析验证判断,同学们有需要可以自己添加。 

上面的代码权限验证和参数验证混合在一起了,大概的流程都是产不多的。在第二步中我把权限验证需要用到的数据当做参数传递到真正的业务方法中,这样的好处是节省了在查询数据库的花费,但是与切面与业务分离的思想有违背的。大家根据具体情况使用吧。

 

 

转载于:https://my.oschina.net/u/2563693/blog/698555

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值