Spring Web利用切面统一处理参数校验异常的方法

Spring Web利用切面统一处理参数校验异常的方法

  关于spring web的参数校验,其过程是通过org.springframework.validation.DataBinder,调用org.springframework.validation.Validator下的validate(Object target, Errors errors)方法。该Validator的实例为org.springframework.validation.beanvalidation.SpringValidatorAdapter。该类内部绑定了javax.validation.Validator的一个实例,一般为org.hibernate.validator.internal.engine.ValidatorImpl。最终整个校验结果被存储在org.springframework.validation.BindingResult的实例中。 

  Controller中关于bindingResult的用法,官网上有一个入门示例.
其中关于参数校验异常的处理是

    if (bindingResult.hasErrors()) {
        return "form";
    }
    return "redirect:/results";

  这就受不了了,难道要在每一个带有@Valid@RequestMapping都这么if…else…一下?好丑…
怎么解决呢?这个时候就需要强大的AOP(切面)了。切面的概念和Spring集成AOP的方法就不在这里介绍了,请读者自行补充。

  那首先来简化官网示例的模型。

  • 需要验证的类为Info:
    public class Info{
        @NotBlank(message="输入信息不能为空")
        private String s;
    }
  • Web Controller为:
    @Controller
    public class WebController{
        @RequestMapping(value="/", method=RequestMethod.POST)
        public Response checkPersonInfo(@Valid Info info, BindingResult bindingResult) {
            if (bindingResult.hasErrors()) {
                return doErrorHandle();
            }
            return doNormalHandle();
        }
    }

  好了,开始加入切面方法吧!

  • 切面的实现为:
    @Aspect
    @Component
    public class ControllerValidatorInterceptor {
        @Around("execution(* com.aerexu.web.*.*(..)) && args(..,bindingResult)")
        public Object doAround(ProceedingJoinPoint pjp, BindingResult bindingResult) throws Throwable {
            Object retVal;
            if (bindingResult.hasErrors()) {
                retVal = doErrorHandle();
            } else {
                retVal = pjp.proceed();
            }
            return retVal;
        }
    }
  • 对应的Web Controller可以简化为:
    @Controller
    public class WebController{
        @RequestMapping(value="/", method=RequestMethod.POST)
        public Response checkPersonInfo(@Valid Info info, BindingResult bindingResult) {
            return doNormalHandle();
        }
    }

  其中,execution(* com.aerexu.web.*.*(..))限定了切面只会尝试切com.aerexu.web包中的方法,args(..,bindingResult)则限定了方法的最后一个参数是BindingResult类型且引用会传递给doAround(ProceedingJoinPoint pjp, BindingResult bindingResult)bindingResult
  当bindingResult含有错误时,则执行doErrorHandle()并返回结果,controller中的方法doNormalHandle()并不会被执行。
  利用这种方式,Controller内部就可以专注于业务处理,参数验证异常的处理完全独立于切面中了。
  如有其它好的实现方式,欢迎讨论。 

  • 12
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值