java 方法参数怎么优雅校验?
怪我咯
怪我咯 2017-04-18 10:42:41
0
5
973
怪我咯
怪我咯

走同样的路,发现不同的人生

全部回覆(5)
阿神

謝謝各位的回答,我覺得此篇部落格的方案比較符合我的預期。

使用SPRING AOP驗證方法參數是否合法

刘奇

不邀自來。這個問題,我之前也考慮過,包括異常處理,都是很繁瑣的,不是核心的業務邏輯,但是充斥在程式碼的各個角落,很繁瑣。
我的解決方案,是透過aop+註解的方式,無侵入式的解決。
1.第一步聲明自訂註解類別

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface RequestRequire {
    
    /**
     * 请求当前接口所需要的参数,多个以小写的逗号隔开
     * @return
     */
    public String require() default "";
    
    /**
    *传递参数的对象类型
    */
    public Class<?> parameter() default Object.class;
}

2.對需要做非空判斷的方法做註解配置(我一般用在controller)

@RequestMapping(value = "/register", method = RequestMethod.POST)
@RequestRequire(require="mobile,sessionToken",parameter=AccountRequestParameter.class)
public void register(HttpServletRequest request,
            HttpServletResponse response,HttpRequestParameter parameter)throws Exception{
        //核心代码
}

AccountRequestParameter類是一個參數類,裡麵包含了帳號模組的所有參數。

3.編寫切面類

@Aspect
@Component
public class RequestRequireAspect {

    Logger log=LoggerFactory.getLogger(RequestRequireAspect.class);
    

    public RequestRequireAspect() {
        log.info("初始化接口参数非空判断切面类...");
    }
    
    @Pointcut("@annotation(com.xxxx.RequestRequire)")
    public void controllerInteceptor() {
    }

    @Around("controllerInteceptor()")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        
        //获取注解的方法参数列表
        Object[] args = pjp.getArgs();
        
        //获取被注解的方法
        MethodInvocationProceedingJoinPoint mjp = (MethodInvocationProceedingJoinPoint) pjp;
        MethodSignature signature = (MethodSignature) mjp.getSignature();
        Method method = signature.getMethod();
        
        //获取方法上的注解
        RequestRequire require = method.getAnnotation(RequestRequire.class);
        
        //以防万一,将中文的逗号替换成英文的逗号
        String fieldNames=require.require().replace(",", ",");
        
        //从参数列表中获取参数对象
        Object parameter=null;
        for(Object pa:args){
            //class相等表示是同一个对象
            if (pa.getClass()==require.parameter() ) {
                parameter=pa;
            }
        }
        
        //通过反射去和指定的属性值判断是否非空
        Class cl=parameter.getClass();
        for(String fieldName:fieldNames.split(",")){
            
            //根据属性名获取属性对象
            Field f=cl.getField(fieldName);
            
            //设置可读写权限
            f.setAccessible(true);
            
            //获取参数值,因为我的参数都是String型所以直接强转
            String value=(String)f.get(parameter);
            
            //非空判断
            if(!StringUtils.isNotBlank(value)){
                throw RuntimeException("参数:"+fieldName+"不允许为空");
            }
        }
        
        //如果没有报错,放行
        return pjp.proceed();
    }
}
  1. 最後在springmvc裡面配置

    <aop:aspectj-autoproxy proxy-target-class="true"/>  

5.最後,你那個方法需要做非空判斷,你就愉快的加上註解吧,不想就把註解移除,非侵入式,可插拔,封裝好了,以後項目都可以直接拿來用。

刘奇

Lombok @NonNull
用法可以看這篇文章

左手右手慢动作

優雅的驗證框架那麼多,為何不google一下。

黄舟

自己寫註解,為什麼不試試validation呢?寫個公共的校驗類別就好了。

熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板