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 boot整合dubbo+zookeeper的详细过程

《Springboot整合dubbo+zookeeper的详细过程》本文讲解SpringBoot整合Dubbo与Zookeeper实现API、Provider、Consumer模式,包含依赖配置、... 目录Spring boot整合dubbo+zookeeper1.创建父工程2.父工程引入依赖3.创建ap

Linux下进程的CPU配置与线程绑定过程

《Linux下进程的CPU配置与线程绑定过程》本文介绍Linux系统中基于进程和线程的CPU配置方法,通过taskset命令和pthread库调整亲和力,将进程/线程绑定到特定CPU核心以优化资源分配... 目录1 基于进程的CPU配置1.1 对CPU亲和力的配置1.2 绑定进程到指定CPU核上运行2 基于

SpringBoot结合Docker进行容器化处理指南

《SpringBoot结合Docker进行容器化处理指南》在当今快速发展的软件工程领域,SpringBoot和Docker已经成为现代Java开发者的必备工具,本文将深入讲解如何将一个SpringBo... 目录前言一、为什么选择 Spring Bootjavascript + docker1. 快速部署与

Spring Boot spring-boot-maven-plugin 参数配置详解(最新推荐)

《SpringBootspring-boot-maven-plugin参数配置详解(最新推荐)》文章介绍了SpringBootMaven插件的5个核心目标(repackage、run、start... 目录一 spring-boot-maven-plugin 插件的5个Goals二 应用场景1 重新打包应用

SpringBoot+EasyExcel实现自定义复杂样式导入导出

《SpringBoot+EasyExcel实现自定义复杂样式导入导出》这篇文章主要为大家详细介绍了SpringBoot如何结果EasyExcel实现自定义复杂样式导入导出功能,文中的示例代码讲解详细,... 目录安装处理自定义导出复杂场景1、列不固定,动态列2、动态下拉3、自定义锁定行/列,添加密码4、合并

Spring Boot集成Druid实现数据源管理与监控的详细步骤

《SpringBoot集成Druid实现数据源管理与监控的详细步骤》本文介绍如何在SpringBoot项目中集成Druid数据库连接池,包括环境搭建、Maven依赖配置、SpringBoot配置文件... 目录1. 引言1.1 环境准备1.2 Druid介绍2. 配置Druid连接池3. 查看Druid监控

Java中读取YAML文件配置信息常见问题及解决方法

《Java中读取YAML文件配置信息常见问题及解决方法》:本文主要介绍Java中读取YAML文件配置信息常见问题及解决方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要... 目录1 使用Spring Boot的@ConfigurationProperties2. 使用@Valu

创建Java keystore文件的完整指南及详细步骤

《创建Javakeystore文件的完整指南及详细步骤》本文详解Java中keystore的创建与配置,涵盖私钥管理、自签名与CA证书生成、SSL/TLS应用,强调安全存储及验证机制,确保通信加密和... 目录1. 秘密键(私钥)的理解与管理私钥的定义与重要性私钥的管理策略私钥的生成与存储2. 证书的创建与

浅析Spring如何控制Bean的加载顺序

《浅析Spring如何控制Bean的加载顺序》在大多数情况下,我们不需要手动控制Bean的加载顺序,因为Spring的IoC容器足够智能,但在某些特殊场景下,这种隐式的依赖关系可能不存在,下面我们就来... 目录核心原则:依赖驱动加载手动控制 Bean 加载顺序的方法方法 1:使用@DependsOn(最直

SpringBoot中如何使用Assert进行断言校验

《SpringBoot中如何使用Assert进行断言校验》Java提供了内置的assert机制,而Spring框架也提供了更强大的Assert工具类来帮助开发者进行参数校验和状态检查,下... 目录前言一、Java 原生assert简介1.1 使用方式1.2 示例代码1.3 优缺点分析二、Spring Fr