suchen

Heim  >  Fragen und Antworten  >  Hauptteil

java 方法参数怎么优雅校验?

怪我咯怪我咯2769 Tage vor978

Antworte allen(5)Ich werde antworten

  • 阿神

    阿神2017-04-18 10:44:41

    谢谢各位的回答,我觉得此篇博客的方案更符合我的预期。

    使用SPRING AOP验证方法参数是否合法

    Antwort
    0
  • 怪我咯

    怪我咯2017-04-18 10:44:41

    不邀自来。这个问题,我之前也考虑过,包括异常处理,都是很繁琐的,不是核心的业务逻辑,但是充斥在代码的各个角落,很繁琐。
    我的解决方案,是通过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.最后,你那个方法需要做非空判断,你就愉快的加上注解吧,不想就把注解移除,非侵入式,可插拔,封装好了,以后项目都可以直接拿来用。

    Antwort
    0
  • 怪我咯

    怪我咯2017-04-18 10:44:41

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

    Antwort
    0
  • ringa_lee

    ringa_lee2017-04-18 10:44:41

    优雅的验证框架那么多,为何不google一下。

    Antwort
    0
  • 黄舟

    黄舟2017-04-18 10:44:41

    自己写注解,为什么不试下validation呢?写个公共的校验类就好了。

    Antwort
    0
  • StornierenAntwort