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();
    }
目录
相关文章
|
14天前
|
Dubbo Java 应用服务中间件
深入探讨了“dubbo+nacos+springboot3的native打包成功后运行出现异常”的原因及解决方案
本文深入探讨了“dubbo+nacos+springboot3的native打包成功后运行出现异常”的原因及解决方案。通过检查GraalVM版本兼容性、配置反射列表、使用代理类、检查配置文件、禁用不支持的功能、查看日志文件、使用GraalVM诊断工具和调整GraalVM配置等步骤,帮助开发者快速定位并解决问题,确保服务的正常运行。
29 1
|
1月前
|
JSON 前端开发 Java
Spring MVC——获取参数和响应
本文介绍了如何在Spring框架中通过不同的注解和方法获取URL参数、上传文件、处理cookie和session、以及响应不同类型的数据。具体内容包括使用`@PathVariable`获取URL中的参数,使用`MultipartFile`上传文件,通过`HttpServletRequest`和`@CookieValue`获取cookie,通过`HttpSession`和`@SessionAttribute`获取session,以及如何返回静态页面、HTML代码片段、JSON数据,并设置HTTP状态码和响应头。
49 1
Spring MVC——获取参数和响应
|
1月前
|
Java API Spring
springBoot:注解&封装类&异常类&登录实现类 (八)
本文介绍了Spring Boot项目中的一些关键代码片段,包括使用`@PathVariable`绑定路径参数、创建封装类Result和异常处理类GlobalException、定义常量接口Constants、自定义异常ServiceException以及实现用户登录功能。通过这些代码,展示了如何构建RESTful API,处理请求参数,统一返回结果格式,以及全局异常处理等核心功能。
|
1月前
|
前端开发 Java Spring
【Spring】“请求“ 之传递单个参数、传递多个参数和传递对象
【Spring】“请求“ 之传递单个参数、传递多个参数和传递对象
110 2
|
1月前
|
Java 关系型数据库 数据库连接
SpringBoot项目使用yml文件链接数据库异常
【10月更文挑战第3天】Spring Boot项目中数据库连接问题可能源于配置错误或依赖缺失。YAML配置文件的格式不正确,如缩进错误,会导致解析失败;而数据库驱动不匹配、连接字符串或认证信息错误同样引发连接异常。解决方法包括检查并修正YAML格式,确认配置属性无误,以及添加正确的数据库驱动依赖。利用日志记录和异常信息分析可辅助问题排查。
186 10
|
1月前
|
Java 关系型数据库 MySQL
SpringBoot项目使用yml文件链接数据库异常
【10月更文挑战第4天】本文分析了Spring Boot应用在连接数据库时可能遇到的问题及其解决方案。主要从四个方面探讨:配置文件格式错误、依赖缺失或版本不兼容、数据库服务问题、配置属性未正确注入。针对这些问题,提供了详细的检查方法和调试技巧,如检查YAML格式、验证依赖版本、确认数据库服务状态及用户权限,并通过日志和断点调试定位问题。
|
2月前
|
Java Spring
spring boot 启动项目参数的设定
spring boot 启动项目参数的设定
|
3月前
|
前端开发 小程序 Java
【规范】SpringBoot接口返回结果及异常统一处理,这样封装才优雅
本文详细介绍了如何在SpringBoot项目中统一处理接口返回结果及全局异常。首先,通过封装`ResponseResult`类,实现了接口返回结果的规范化,包括状态码、状态信息、返回信息和数据等字段,提供了多种成功和失败的返回方法。其次,利用`@RestControllerAdvice`和`@ExceptionHandler`注解配置全局异常处理,捕获并友好地处理各种异常信息。
1170 0
【规范】SpringBoot接口返回结果及异常统一处理,这样封装才优雅
|
3月前
|
监控 安全 Java
【开发者必备】Spring Boot中自定义注解与处理器的神奇魔力:一键解锁代码新高度!
【8月更文挑战第29天】本文介绍如何在Spring Boot中利用自定义注解与处理器增强应用功能。通过定义如`@CustomProcessor`注解并结合`BeanPostProcessor`实现特定逻辑处理,如业务逻辑封装、配置管理及元数据分析等,从而提升代码整洁度与可维护性。文章详细展示了从注解定义、处理器编写到实际应用的具体步骤,并提供了实战案例,帮助开发者更好地理解和运用这一强大特性,以实现代码的高效组织与优化。
182 0
|
2月前
|
SQL 监控 druid
springboot-druid数据源的配置方式及配置后台监控-自定义和导入stater(推荐-简单方便使用)两种方式配置druid数据源
这篇文章介绍了如何在Spring Boot项目中配置和监控Druid数据源,包括自定义配置和使用Spring Boot Starter两种方法。