admin管理员组

文章数量:1516870

说明:

(1) 本篇博客的逻辑:

为什么写本篇博客?: 在【 】中,Controller处接收参数的时候,当我们通过AddCategoryReq这个bean接收到参数后,我们需要校验下参数是否为空;在这篇博客中,我们采用笨笨的方式去校验;

显然,在多时候我们都需要进行参数校验;比如上面的非空检验等;而,为了能够更加优雅的实现参数校验,于是就引出了本篇博客介绍的@Valid注解;

● 但是,在使用@Valid注解时候,引入的一个新问题: 但是,在使用@Valid参数校验时候,如果校验失败,其引发的异常是【MethodArgumentNotValidException异常】;但是,我们在GlobalExceptionHandler中并没有特别处理这种异常(而是用Exception这种粗粒度的方式,去处理了),所以就出现了返回信息太宽泛,没有反映出具体错误信息的情况;

● 解决策略(这也是本篇博客重难点): 在GlobalExceptionHandler编写对应的方法去处理【MethodArgumentNotValidException异常】,以能根据【MethodArgumentNotValidException异常的具体错误信息】去构建对应的APIRestResponse统一返回对象 ;(这其中涉及到了如【getBindingResult()】、【BindingResult.hasErrors()】、【BindingResult.getAllErrors()】、【objectError.getDefaultMessage()】等与Validation校验异常相关的方法)

目录


一:参数校验的注解:【@Valid】,【@NotNull,@Max(value),@Size(max,min)】:简述;

说明:

(1) 如果我们在Controller处,给某个入参添加上@Valid注解,就表示这个入参需要校验;@Valid注解就像一个开关一样,用了这个注解就表示开启校验,不用这个注解就表示不用校验;

(2) @NotNULL,@Max(value),@Size(max,min)表示了校验规则;可以根据校验需求,在对应的属性上,使用这些注解;

(3) 单纯看这些描述,可能云里雾里;具体,看下下面的案例;


二:参数校验的注解:【@Valid】,【@NotNULL,@Max(value),@Size(max,min)】:案例演示;

1.【@Valid】,【@NotNULL,@Max(value),@Size(max,min)】:使用案例;

说明:

(1) Spring Boot2.3版本将不再内部依赖validator;所以对于2.3以后的版本,如果还想使用@Valid参数校验,需要自己先手动引入validator依赖。

2.启动项目,实测;以及引出新的问题(参数校验引发的【MethodArgumentNotValidException异常】没有去单独处理);

(1)测试结果:参数校验生效了;

看下控制台的异常日志信息:

org.springframework.web.bind.MethodArgumentNotValidException: Validation failed for argument [1] in public com.imooc.mall.common.ApiRestResponse com.imooc.mall.controller.CategoryController.addCategory(javax.servlet.http.HttpSession,com.imooc.mall.model.request.AddCategoryReq): [Field error in object 'addCategoryReq' on field 'name': rejected value [测试类别1额方法地方]; codes [Size.addCategoryReq.name,Size.name,Size.java.lang.String,Size]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [addCategoryReq.name,name]; arguments []; default message [name],5,2]; default message [个数必须在2和5之间]] 
	at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.resolveArgument(RequestResponseBodyMethodProcessor.java:139) ~[spring-webmvc-5.2.1.RELEASE.jar:5.2.1.RELEASE]
	at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:121) ~[spring-web-5.2.1.RELEASE.jar:5.2.1.RELEASE]
	at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:167) ~[spring-web-5.2.1.RELEASE.jar:5.2.1.RELEASE]
	at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:134) ~[spring-web-5.2.1.RELEASE.jar:5.2.1.RELEASE]
	at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:106) ~[spring-webmvc-5.2.1.RELEASE.jar:5.2.1.RELEASE]
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:888) ~[spring-webmvc-5.2.1.RELEASE.jar:5.2.1.RELEASE]
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:793) ~[spring-webmvc-5.2.1.RELEASE.jar:5.2.1.RELEASE]
	at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.2.1.RELEASE.jar:5.2.1.RELEASE]
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040) [spring-webmvc-5.2.1.RELEASE.jar:5.2.1.RELEASE]
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943) [spring-webmvc-5.2.1.RELEASE.jar:5.2.1.RELEASE]
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) [spring-webmvc-5.2.1.RELEASE.jar:5.2.1.RELEASE]
	at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909) [spring-webmvc-5.2.1.RELEASE.jar:5.2.1.RELEASE]

日志信息,很明确:

至此,说明参数校验已经生效了;

……………………………………………………

(2)仍存问题:系统异常处理粒度太大:没有去单独处理参数校验引发的【MethodArgumentNotValidException异常】;

但是,还有个问题:上面出现了错误后,详细的提示信息只出现在了日志中,我们程序员是可以看到的;但是,我们这个商城的用户却不能知道具体的错误原因,商城的用户只能得到“系统异常”这个笼统的错误信息;

可以看到,上面抛出的异常是【MethodArgumentNotValidException】;而,这个异常是是继承自Exception的;

本文标签: 异常说明编程