SpringBoot 全局异常统一处理:BindException(绑定异常)

本文主要是介绍SpringBoot 全局异常统一处理:BindException(绑定异常),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

概述

在Spring Boot应用中,数据绑定是一个至关重要的环节,它负责将HTTP请求中的参数映射到控制器方法的入参对象上。在这个过程中如果遇到任何问题,如参数缺失、类型不匹配或验证失败等,Spring MVC将会抛出一个org.springframework.validation.BindException异常。本文将深入解析BindException异常的原因和处理方式。

数据绑定异常的来源

BindException通常与数据绑定和参数校验紧密相关。当用户通过HTTP请求向服务器发送数据时,Spring MVC框架会尝试自动将这些请求参数绑定到控制器方法的入参对象上。如果在这个过程中发生以下情况,就可能引发BindException异常:

  1. 参数映射错误:请求中的参数未能正确地映射到目标对象的属性上。
  2. 注解校验失败:对象属性使用了javax.validation或者org.springframework.validation包下的注解进行校验(如@NotNull、@Size等),而传入的值不符合这些注解所定义的约束条件。

具体应用场景示例

本段所说的 请求参数,均指的是控制器方法的入参对象的属性。

  • 必填字段为空:若某个字段标记为@NotBlank但未接收到对应的请求参数,则会触发BindException异常。
  • 数据格式不匹配:例如,尝试将请求参数的字符串值转换为目标类型(如整数或日期)时无法成功转换。
  • 字段长度超出限制:对于有最大或最小长度限制的字段,当请求参数的长度超过这些限制时,会引发异常。
  • 正则表达式不匹配:当字段的值需满足特定的正则表达式模式,而实际提供的参数不满足该模式时,也会导致异常。
  • 自定义验证逻辑失败:通过@Valid注解配合自定义验证器进行参数校验时,如果验证失败,同样会抛出BindException异常。

异常处理代码

核心代码

在Spring Boot应用中,我们可以利用@ExceptionHandler注解来捕获并处理BindException异常,如下所示的代码片段提供了一种通用的异常处理策略:

    /*** 参数校验异常:对象参数校验。*/@ExceptionHandler@ResponseStatus(HttpStatus.BAD_REQUEST)public Result<Void> handleException(BindException e, HandlerMethod handlerMethod) {logInfo(e, handlerMethod);List<FieldError> fieldErrors = e.getFieldErrors();String userMessage = UserTipGenerator.getUserMessage(fieldErrors);String errorMessageCore = ErrorMessageGenerator.getErrorMessage(fieldErrors);String errorMessage = String.format("【参数校验异常】(错误数量:%s):%s", e.getErrorCount(), errorMessageCore);return Result.fail(userMessage, String.valueOf(HttpStatus.BAD_REQUEST.value()), errorMessage);}

上述代码中,当出现BindException异常时,系统将返回一个状态码为400(Bad Request)的结果,并附带详细的错误信息,包括哪个字段校验失败以及失败原因。

相关代码:UserTipGenerator,ErrorMessageGenerator

在这里插入图片描述

在这里插入图片描述

详细代码,请参考后面的参考文章《SpringBoot 全局异常统一处理(AOP):@RestControllerAdvice + @ExceptionHandler + @ResponseStatus》

测试案例

1. 必填字段为空

测试代码

假设我们有一个新增用户的接口,其中入参要求不能为空:

    @PostMapping("users")@Operation(summary = "新增用户")public void addUser(@Valid @RequestBody UserAddParam param) {log.info("测试:新增用户,Post请求。param={}", param);}
package com.example.web.response.model.param;import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;import javax.validation.constraints.NotBlank;@Data
@Schema(name = "新增用户Param")
public class UserAddParam {@NotBlank(message = "姓名,不能为空")@Schema(description = "姓名", example = "张三")private String name;// ...
}

在这里插入图片描述

未处理时情况

  • 请求响应

在这里插入图片描述

  • 控制台的错误日志

在这里插入图片描述

处理后接口请求响应

在这里插入图片描述

2. 数据格式不匹配

一下两种情况,会导致出现数据格式异常:

  1. 输入无法成功转换指定的数字类型。比如,入参的数据类型为整数Integer,但输入为:[张三] 。
  2. 输入的值超过允许的最大值。比如,入参的数据类型为整数Integer,但输入为:[1234567890123456789],而Integer的最大值为[231-1,即 2147483647] ;此时内嵌的异常为 NumberFormatException

测试代码

    @GetMapping(path = "users")@Operation(summary = "查询用户列表", description = "测试:BindException。参数校验异常:Get请求,Query参数,以对象的形式接收。")public List<UserVO> listUsers(@Valid UserQuery userQuery, PageQuery pageQuery,HttpServletRequest request, HttpServletResponse response, HttpSession session) {log.info("查询用户列表。userQuery={},pageQuery={}", userQuery, pageQuery);// 业务代码...}
package com.example.core.model;import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import org.springdoc.api.annotations.ParameterObject;@Data
@ParameterObject
@Schema(name = "分页参数Query")
public class PageQuery {@Schema(description = "当前页码", type = "Integer", defaultValue = "1", example = "1", minimum = "1")private Integer pageNumber = 1;@Schema(description = "每 1 页的数据量", type = "Integer", defaultValue = "10", example = "10", minimum = "1", maximum = "100")private Integer pageSize = 10;}

未处理的情况

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

处理后接口请求响应

在这里插入图片描述

在这里插入图片描述

3. 自定义验证逻辑失败

参考相关专栏:《SpringBoot - 接口参数校验》

总结

在没有处理BindException的情况下,如果客户端提交了缺少必要参数的请求,服务端将返回包含错误信息的标准HTTP响应,并在控制台打印详细的错误日志。而经过上述异常处理器处理后,客户端接收到的响应将以更友好的格式呈现错误详情,便于快速定位和修复问题。

通过适当地处理BindException异常,不仅可以提升应用的健壮性,还能优化用户体验,使得API接口的错误反馈更加清晰明确。

参考文章

SpringBoot 全局异常统一处理(AOP):@RestControllerAdvice + @ExceptionHandler + @ResponseStatus

这篇关于SpringBoot 全局异常统一处理:BindException(绑定异常)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/611934

相关文章

Spring WebClient从入门到精通

《SpringWebClient从入门到精通》本文详解SpringWebClient非阻塞响应式特性及优势,涵盖核心API、实战应用与性能优化,对比RestTemplate,为微服务通信提供高效解决... 目录一、WebClient 概述1.1 为什么选择 WebClient?1.2 WebClient 与

Java.lang.InterruptedException被中止异常的原因及解决方案

《Java.lang.InterruptedException被中止异常的原因及解决方案》Java.lang.InterruptedException是线程被中断时抛出的异常,用于协作停止执行,常见于... 目录报错问题报错原因解决方法Java.lang.InterruptedException 是 Jav

Python进行JSON和Excel文件转换处理指南

《Python进行JSON和Excel文件转换处理指南》在数据交换与系统集成中,JSON与Excel是两种极为常见的数据格式,本文将介绍如何使用Python实现将JSON转换为格式化的Excel文件,... 目录将 jsON 导入为格式化 Excel将 Excel 导出为结构化 JSON处理嵌套 JSON:

深入浅出SpringBoot WebSocket构建实时应用全面指南

《深入浅出SpringBootWebSocket构建实时应用全面指南》WebSocket是一种在单个TCP连接上进行全双工通信的协议,这篇文章主要为大家详细介绍了SpringBoot如何集成WebS... 目录前言为什么需要 WebSocketWebSocket 是什么Spring Boot 如何简化 We

java中pdf模版填充表单踩坑实战记录(itextPdf、openPdf、pdfbox)

《java中pdf模版填充表单踩坑实战记录(itextPdf、openPdf、pdfbox)》:本文主要介绍java中pdf模版填充表单踩坑的相关资料,OpenPDF、iText、PDFBox是三... 目录准备Pdf模版方法1:itextpdf7填充表单(1)加入依赖(2)代码(3)遇到的问题方法2:pd

Java Stream流之GroupBy的用法及应用场景

《JavaStream流之GroupBy的用法及应用场景》本教程将详细介绍如何在Java中使用Stream流的groupby方法,包括基本用法和一些常见的实际应用场景,感兴趣的朋友一起看看吧... 目录Java Stream流之GroupBy的用法1. 前言2. 基础概念什么是 GroupBy?Stream

SpringBoot监控API请求耗时的6中解决解决方案

《SpringBoot监控API请求耗时的6中解决解决方案》本文介绍SpringBoot中记录API请求耗时的6种方案,包括手动埋点、AOP切面、拦截器、Filter、事件监听、Micrometer+... 目录1. 简介2.实战案例2.1 手动记录2.2 自定义AOP记录2.3 拦截器技术2.4 使用Fi

最新Spring Security的基于内存用户认证方式

《最新SpringSecurity的基于内存用户认证方式》本文讲解SpringSecurity内存认证配置,适用于开发、测试等场景,通过代码创建用户及权限管理,支持密码加密,虽简单但不持久化,生产环... 目录1. 前言2. 因何选择内存认证?3. 基础配置实战❶ 创建Spring Security配置文件

Spring Security 单点登录与自动登录机制的实现原理

《SpringSecurity单点登录与自动登录机制的实现原理》本文探讨SpringSecurity实现单点登录(SSO)与自动登录机制,涵盖JWT跨系统认证、RememberMe持久化Token... 目录一、核心概念解析1.1 单点登录(SSO)1.2 自动登录(Remember Me)二、代码分析三、

springboot自定义注解RateLimiter限流注解技术文档详解

《springboot自定义注解RateLimiter限流注解技术文档详解》文章介绍了限流技术的概念、作用及实现方式,通过SpringAOP拦截方法、缓存存储计数器,结合注解、枚举、异常类等核心组件,... 目录什么是限流系统架构核心组件详解1. 限流注解 (@RateLimiter)2. 限流类型枚举 (