spring-boot-validator参数校验系列(4)--------自定义参数校验异常

简介: 自定义参数校验返回数据格式

前言

目录

spring-boot-validator参数校验系列(1)--------基本参数校验

spring-boot-validator参数校验系列(2)--------分组校验

spring-boot-validator参数校验系列(3)--------自定义校验注解

spring-boot-validator参数校验系列(4)--------自定义参数校验异常

一、为什么要自定义参数校验异常?

为了统一返回格式,方便前端处理并给出提示!

二、如何实现?

一般的web开发,我们都会采取统一得返回格式,让接口调用者能有效的处理。比如下面这种。

{
"data": {
//具体的返回内容    },
"rtn_flag": 9999,  //状态码"rtn_msg": "操作成功"//状态消息}

如果不对参数校验进行捕获,会出现什么吗格式呢?

{
"timestamp": "2021-09-13T09:30:28.862+00:00",
"status": 400,
"error": "Bad Request",
"trace": "org.springframework.web.bind.MethodArgumentNotValidException: Validation failed for argument [0] in public void com.tab343.myspringboot.validation.MyValidationController.custom(com.tab343.myspringboot.validation.MyPerson) with 3 errors: [Field error in object 'myPerson' on field 'mobile': rejected value [null]; codes [NotBlank.myPerson.mobile,NotBlank.mobile,NotBlank.java.lang.String,NotBlank]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [myPerson.mobile,mobile]; arguments []; default message [mobile]]; default message [不能为空]] [Field error in object 'myPerson' on field 'sex': rejected value [3]; codes [Fixed.myPerson.sex,Fixed.sex,Fixed.java.lang.Integer,Fixed]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [myPerson.sex,sex]; arguments []; default message [sex],[Ljava.lang.String;@66923162]; default message [请输入合法值!]] [Field error in object 'myPerson' on field 'email': rejected value [null]; codes [NotBlank.myPerson.email,NotBlank.email,NotBlank.java.lang.String,NotBlank]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [myPerson.email,email]; arguments []; default message [email]]; default message [不能为空]] \r\n\tat org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.resolveArgument(RequestResponseBodyMethodProcessor.java:141)\r\n\tat org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:121)\r\n\tat org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:170)\r\n\tat org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:137)\r\n\tat org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:106)\r\n\tat org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895)\r\n\tat org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808)\r\n\tat org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)\r\n\tat org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1064)\r\n\tat org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963)\r\n\tat org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)\r\n\tat org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909)\r\n\tat javax.servlet.http.HttpServlet.service(HttpServlet.java:681)\r\n\tat org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)\r\n\tat javax.servlet.http.HttpServlet.service(HttpServlet.java:764)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\r\n\tat org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\r\n\tat org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)\r\n\tat org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\r\n\tat org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)\r\n\tat org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\r\n\tat org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)\r\n\tat org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)\r\n\tat org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)\r\n\tat org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197)\r\n\tat org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)\r\n\tat org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542)\r\n\tat org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135)\r\n\tat org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)\r\n\tat org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)\r\n\tat org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357)\r\n\tat org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:382)\r\n\tat org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)\r\n\tat org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:893)\r\n\tat org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1726)\r\n\tat org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)\r\n\tat org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)\r\n\tat org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)\r\n\tat org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)\r\n\tat java.lang.Thread.run(Thread.java:748)\r\n",
"message": "Validation failed for object='myPerson'. Error count: 3",
"errors": [
        {
"codes": [
"Fixed.myPerson.sex",
"Fixed.sex",
"Fixed.java.lang.Integer",
"Fixed"            ],
"arguments": [
                {
"codes": [
"myPerson.sex",
"sex"                    ],
"arguments": null,
"defaultMessage": "sex",
"code": "sex"                },
                [
"0",
"1"                ]
            ],
"defaultMessage": "请输入合法值!",
"objectName": "myPerson",
"field": "sex",
"rejectedValue": 3,
"bindingFailure": false,
"code": "Fixed"        },
    ],
"path": "/validation/custom"}

可以看到错误输出还是很详细的,但是与之前的格式不符,如果是对接的话,还需要重新写一套解析方法。这里我们可以采用@RestControllerAdvice、@ControllerAdvice实现异常捕获并更改格式。

@RestControllerAdvicepublicclassGlobalExceptionHandler {
privatestaticfinalLoggerlog=LoggerFactory.getLogger(GlobalExceptionHandler.class);
/*** 请求参数校验未通过*/@ExceptionHandler(MethodArgumentNotValidException.class)
publicAjaxResultmethodArgumentNotValidException(BindExceptionex){
FieldErrorfe=ex.getFieldError();
returnAjaxResult.error(fe.getField().concat(fe.getDefaultMessage()));
    }
}

(1)为什么是捕获MethodArgumentNotValidException异常呢?

这里我是直接根据报错输出的json来的。

(2)而如何获取注解中提示消息(即message = "请填写id!")呢?

可以我们可以参照MethodArgumentNotValidException类的toString()方法!可以看到,此方法获取错误后,在循环中拼接错误信息,然后形成我们刚看到的错误json。

publicStringgetMessage() {
StringBuildersb= (newStringBuilder("Validation failed for argument [")).append(this.parameter.getParameterIndex()).append("] in ").append(this.parameter.getExecutable().toGenericString());
if (this.bindingResult.getErrorCount() >1) {
sb.append(" with ").append(this.bindingResult.getErrorCount()).append(" errors");
        }
sb.append(": ");
Iteratorvar2=this.bindingResult.getAllErrors().iterator();
while(var2.hasNext()) {
ObjectErrorerror= (ObjectError)var2.next();
sb.append("[").append(error).append("] ");
        }
returnsb.toString();
    }
目录
相关文章
|
1月前
|
Java 数据库连接 Spring
Spring Boot命令行启动添加参数
Spring Boot命令行启动添加参数
|
1月前
|
JSON 前端开发 Java
解决Spring MVC中No converter found for return value of type异常
在Spring MVC开发中遇到`No converter found for return value of type`异常,通常是因缺少消息转换器、返回值类型不支持或转换器优先级配置错误。解决方案包括:1) 添加对应的消息转换器,如`MappingJackson2HttpMessageConverter`;2) 自定义消息转换器并实现`HttpMessageConverter`接口,设置优先级;3) 修改返回值类型为如`ResponseEntity`的合适类型。通过这些方法可确保返回值正确转换为响应内容。
39 1
|
2天前
|
Java
springboot全局自定义异常
springboot全局自定义异常
|
7天前
|
前端开发 Java
SpringBoot之自定义注解参数校验
SpringBoot之自定义注解参数校验
16 2
|
11天前
|
Java 微服务 Spring
Spring Boot中获取配置参数的几种方法
Spring Boot中获取配置参数的几种方法
21 2
|
17天前
|
开发框架 Java 开发者
Spring Boot接收参数的多种方式
【4月更文挑战第20天】
13 0
|
18天前
|
XML 人工智能 Java
Spring Bean名称生成规则(含源码解析、自定义Spring Bean名称方式)
Spring Bean名称生成规则(含源码解析、自定义Spring Bean名称方式)
|
23天前
|
JSON Java 数据格式
Spring Boot实现各种参数校验
这些是Spring Boot中实现参数校验的一些常见方法,你可以根据项目需求选择适合的方式来进行参数校验。
16 0
|
1月前
|
前端开发 Java Spring
参数解密:揭示Spring MVC请求参数处理的实际应用指南
参数解密:揭示Spring MVC请求参数处理的实际应用指南
26 1
|
1月前
|
Java Spring
自定义转换之美:深入Spring自定义类型转换器的奥秘
自定义转换之美:深入Spring自定义类型转换器的奥秘
15 0