Spring Boot电商项目24:商品分类模块三:使用【@Valid注解】校验入参;(重点是:处理MethodArgumentNotValidException异常的信息,构建API统一返回对象)

说明:

(1)本篇博客的逻辑:

          ● 为什么写本篇博客?:在【Spring Boot电商项目23:商品分类模块二:【增加目录分类】接口;(接收请求中的、放在body中的参数时候,使用了@RequestBody;)】中,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)】:简述;

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

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

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

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

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

三:在【GlobalExceptionHandler】中,去处理【MethodArgumentNotValidException异常】:根据该异常的具体信息,去构建ApiRestResponse统一返回对象;

1.思路梳理;

2.在【GlobalExceptionHandler】中,去处理【MethodArgumentNotValidException异常】:根据该异常的具体信息,去构建ApiRestResponse统一返回对象;(重难点!)

(1)方法说明:拦截【MethodArgumentNotValidException异常】,打印日志,去构建ApiRestResponse统一返回对象;

(2)【getBindingResult()】说明(不准确,可能存在错误);

(3)【BindingResult】:这是个接口;

(4)【BindingResult.hasErrors()】:bindingResult.hasErrors()是为了验证@Validated后面bean 里是否有不符合校验条件的错误信息;

(5)【BindingResult.getAllErrors()】(方法返回值类型是【List】):获取参数校验时的,所有错误;

(6)【ObjectError】:可以理解为是一个【封装了Validation校验错误】的对象;(理解,可能不准确……) 

(7)【getDefaultMessage()】:获取错误的具体信息;

(8)方法说明:提取错误信息,将其添加到一个List集合中;

(9)方法说明:根据从【MethodArgumentNotValidException异常】中,提取的具体错误信息,构建ApiRestResponse统一返回对象; 

3.启动项目,观察效果;

(1)效果;

(2)完善:设置为空时,具体的信息:@NotNull(message="***不能为空");

四:Summary:

1.当我们在GlobalExceptionHandler中,书写了这个【处理MethodArgumentNotValidException异常的逻辑】后;;;;我们在需要参数校验的地方,就可以放心大胆的去使用Validation参数校验去校验参数了;

2.额外的补充说明: (这儿的总结还是比较重要的)


一:参数校验的注解:【@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异常】;

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

  • 10
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值