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

这篇具有很好参考价值的文章主要介绍了SpringBoot 全局异常统一处理:BindException(绑定异常)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

概述

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

  • 本文仅详细解析 BindException 的异常处理;
  • 关于 全局异常统一处理 的原理和完整实现逻辑,请参考文章:《SpringBoot 全局异常统一处理(AOP):@RestControllerAdvice + @ExceptionHandler + @ResponseStatus》

数据绑定异常的来源

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

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

具体应用场景示例

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

  • 必填字段为空(或空白):若某个字符串类型的字段标记为@NotBlank,但未接收到对应的参数或参数为空白(不包含非空格的字符),则会触发BindException异常。@NotNull、@NotEmpty 的逻辑类似,校验失败也会触发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 全局异常统一处理:BindException(绑定异常),# 全局异常统一处理(SpringMVC),spring boot,后端,java,异常统一处理

SpringBoot 全局异常统一处理:BindException(绑定异常),# 全局异常统一处理(SpringMVC),spring boot,后端,java,异常统一处理

详细代码,请参考后面的参考文章《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;
    
    // ...
}

SpringBoot 全局异常统一处理:BindException(绑定异常),# 全局异常统一处理(SpringMVC),spring boot,后端,java,异常统一处理

未处理时情况

  • 请求响应

SpringBoot 全局异常统一处理:BindException(绑定异常),# 全局异常统一处理(SpringMVC),spring boot,后端,java,异常统一处理

  • 控制台的错误日志

SpringBoot 全局异常统一处理:BindException(绑定异常),# 全局异常统一处理(SpringMVC),spring boot,后端,java,异常统一处理

处理后接口请求响应

SpringBoot 全局异常统一处理:BindException(绑定异常),# 全局异常统一处理(SpringMVC),spring boot,后端,java,异常统一处理

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;

}

未处理的情况

SpringBoot 全局异常统一处理:BindException(绑定异常),# 全局异常统一处理(SpringMVC),spring boot,后端,java,异常统一处理

SpringBoot 全局异常统一处理:BindException(绑定异常),# 全局异常统一处理(SpringMVC),spring boot,后端,java,异常统一处理

SpringBoot 全局异常统一处理:BindException(绑定异常),# 全局异常统一处理(SpringMVC),spring boot,后端,java,异常统一处理
SpringBoot 全局异常统一处理:BindException(绑定异常),# 全局异常统一处理(SpringMVC),spring boot,后端,java,异常统一处理

处理后接口请求响应

SpringBoot 全局异常统一处理:BindException(绑定异常),# 全局异常统一处理(SpringMVC),spring boot,后端,java,异常统一处理

SpringBoot 全局异常统一处理:BindException(绑定异常),# 全局异常统一处理(SpringMVC),spring boot,后端,java,异常统一处理

3. 自定义验证逻辑失败

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

总结

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

通过适当地处理BindException异常,不仅可以提升应用的健壮性,还能优化用户体验,使得API接口的错误反馈更加清晰明确。文章来源地址https://www.toymoban.com/news/detail-799629.html

到了这里,关于SpringBoot 全局异常统一处理:BindException(绑定异常)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【SpringMVC】JSON注解&全局异常处理机制

    🎉🎉欢迎来到我的CSDN主页!🎉🎉 🏅我是 Java方文山 ,一个在CSDN分享笔记的博主。📚📚 🌟在这里,我要推荐给大家我的专栏《Spring MVC》。🎯🎯 🚀无论你是编程小白,还是有一定基础的程序员,这个专栏都能满足你的需求。我会用最简单易懂的语言,带你走进Spring

    2024年02月08日
    浏览(37)
  • 【SpringMVC】统一异常处理 前后台协议联调 拦截器

    1. 问题描述 在讲解这一部分知识点之前,我们先来演示个效果,修改BookController类的 getById 方法 重新启动运行项目,使用PostMan发送请求,当传入的id为1,则会出现如下效果: 前端接收到这个信息后和之前我们约定的格式不一致,这个问题该如何解决? 在解决问题之前,我们

    2024年02月11日
    浏览(49)
  • 【SpringMVC】统一异常处理 前后台协议联调 拦截器(文末赠书)

    1. 问题描述 在讲解这一部分知识点之前,我们先来演示个效果,修改BookController类的 getById 方法 重新启动运行项目,使用PostMan发送请求,当传入的id为1,则会出现如下效果: 前端接收到这个信息后和之前我们约定的格式不一致,这个问题该如何解决? 在解决问题之前,我们

    2024年02月09日
    浏览(46)
  • springboot全局统一返回处理

    项目中一般都会有规定好的接口返回格式,无论成功与失败,一般格式都是不变的,这样是为了方便前后端统一处理,今天就来说下前后端统一处理的较为优雅的方式; 一般而言都会有一个统一的返回类作为接口的返回数据的封装,例如: 然后我们通过此类作为返回参数的统一封装

    2024年02月13日
    浏览(39)
  • SpringBoot统一异常处理和统一返回格式

    上篇博客我们讲解了使用AOP来进行统一的用户登录判断,其实像这种功能统一且使用较多的地方,都可以用AOP来处理,除了统⼀的⽤户登录判断之外,AOP 还可以实现: 统⼀⽇志记录 统⼀⽅法执⾏时间统计 (在性能优化阶段,监控流量,接口的响应时间等甚至每个方法的响应

    2024年02月15日
    浏览(35)
  • springboot 统一异常处理 + 日志记录

          在项目的开发中,在某些情况下,比如非业务的操作,日志记录,权限认证和异常处理等。我们需要对客户端发出的请求进行拦截,常用的API拦截方式有Fliter,Interceptor,ControllerAdvice以及Aspect。先简单介绍一下不同的拦截方式。 可以获得Http原始的请求和响应信息,

    2023年04月17日
    浏览(46)
  • springboot全局异常处理和自定义异常处理

    在spring项目中,优雅处理异常,好处是可以将系统产生的全部异常统一捕获处理,自定义的异常也由全局异常来捕获,如果涉及到validator参数校验器使用全局异常捕获也是较为方便。 GlobalExceptionHandler类: 自定义异常CustomException类: 通用返回类:AjaxResult 枚举类ResultCodeEnum:

    2024年02月04日
    浏览(42)
  • SpringBoot全局异常处理源码

    今天这里叙述的全局异常处理是SpringBoot在Servlet场景下的处理机制,重点是 Servlet 模式,当然 WEBFLUX 今天不做过多描述,SpringBoot2.2.x以后引入的一种响应式web开发,在SpringBoot启动类中可以看到: deduceFromClasspath 方法: 既然是SringBoot的webServlet场景,自然不可以放过的就是 Dis

    2024年02月07日
    浏览(46)
  • SpringBoot第14讲:SpringBoot 如何统一异常处理

    本文是SpringBoot第14讲,SpringBoot接口如何对异常进行统一封装,并统一返回呢?以上文的参数校验为例, 如何优雅的将参数校验的错误信息统一处理并封装返回呢

    2024年02月11日
    浏览(48)
  • SpringBoot全局异常页面处理学习

    首先我们先在控制器中写一个异常,默认情况下我们的SpringBoot异常页面是这个样子的。 示例代码如下:  一、自定义静态异常页面 自定义静态异常页面,我们可以分成两种方式,第一种就是使用HTTP状态码来命名页面,例如404.html,403.html,500html等。另一种就是直接定义一个4

    2024年02月09日
    浏览(48)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包