spring Aop 實現對http請求參數的驗證,及對功能權限的驗證

Aop 面向切面編程,在java 中廣泛使用動態代理和反射實現。具體的請百度。spring aop有多種方式。本次使用的是註解方式,(建議使用註解方式)。java

第一步自定義了2個註解spring

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

}編程

public @interface FieldVerify {ui

    boolean required() default true;
    
    /***
     * 數據類型primary 基本數據
     * creator mingqiang_zhou
     * createdate 2016-6-16
     * modifyor 
     * @return
     */
    String type() default "primary";    
}
 .net

第二步、創建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;get

........      
        Opportunity opportunity = null;
        if(RightConstant.ACT_ADD.equals(chktype)){
            //檢查添加權限
        }else{
            //須要數據進行驗證權限it

           。。。。
            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;
    }

這個解析是十分簡單的驗證十分有數據,沒有對數據的具體內容進行解析驗證判斷,同窗們有須要能夠本身添加。 

上面的代碼權限驗證和參數驗證混合在一塊兒了,大概的流程都是產很少的。在第二步中我把權限驗證須要用到的數據當作參數傳遞到真正的業務方法中,這樣的好處是節省了在查詢數據庫的花費,可是與切面與業務分離的思想有違背的。你們根據具體狀況使用吧。

相關文章
相關標籤/搜索