SpringMvc @Valid如何抛出拦截异常

Spring MVC 中的 @Valid 注解可以用来验证提交的数据是否满足指定的规则和条件,但是如果数据不符,则需要抛出异常给前端。

下面是使用 @Valid 注解实现异常拦截的步骤:

  1. 在 Controller 的方法参数中添加注解 @Valid 和 BindingResult 对象。

  2. 编写数据验证规则,通常是在数据实体类中使用注解编写。

  3. 在 Controller 方法调用时,Spring MVC 会自动对提交的数据进行验证,如果不符配置要求,则会自动将错误信息封装成 BindingResult 对象,并将其作为参数传入 Controller 方法中。

  4. 在 Controller 方法中判断 BindingResult 对象中是否包含错误信息,如果包含,则可以将错误信息通过异常抛出给前端。

下面是使用 @Valid 注解抛出异常的示例:

  1. 新建一个数据实体类 User.java,其中包含用户名和密码两个属性。在类上加上注解 @Validated。
@Validated
public class User {

    @NotEmpty(message = "用户名不能为空")
    private String username;

    @NotNull(message = "密码不能为空")
    private String password;

    // getter and setter
}
  1. 在 Controller 中添加一个方法来接收前端传来的 User 对象,验证是否符合规则。如果不符合,抛出异常。
@PostMapping("/")
@ResponseBody
public ResponseData createUser(@RequestBody @Valid User user, BindingResult result){
    if(result.hasErrors()){
        List<String> msgs = result.getAllErrors().stream()
                .map(DefaultMessageSourceResolvable::getDefaultMessage)
                .collect(Collectors.toList());
        throw new ApiException(ResponseCode.PARAMETER_ERROR, String.join(";", msgs));
    }
    // 保存用户数据
    return new ResponseData();
}

在这个方法中,我们处理了参数 "user",并将其与注解 @Valid 一起使用,Spring MVC 会在处理该方法之前自动执行验证。然后通过 BindingResult 捕获验证结果,并判断是否有错误。如果有,则将错误返回给前端。

  1. 添加一个全局异常处理器来捕获抛出的异常并返回错误信息。
@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(ApiException.class)
    public ResponseData handleApiException(ApiException e) {
        //将异常信息封装到 ResponseData 对象中,返回给前端
        return new ResponseData(e.getCode(), e.getMessage());
    }

    @ExceptionHandler(Exception.class)
    public ResponseData handleException(Exception e) {
        //将异常信息封装到 ResponseData 对象中,返回给前端
        return new ResponseData(ResponseCode.SERVER_ERROR);
    }
}

在这个全局异常处理器中,我们使用 @RestControllerAdvice 注解来标注这是一个全局异常处理器,然后使用 @ExceptionHandler 注解来指定当某个类型的异常抛出时,应该调用处理它的方法。

下面是一个完整的示例代码:

@RestController
@RequestMapping("/user")
@Validated
public class UserController {

    @PostMapping("/")
    public void createUser(@RequestBody @Valid User user, BindingResult result) {
        if (result.hasErrors()) {
            List<String> msgs = result.getAllErrors().stream()
                    .map(DefaultMessageSourceResolvable::getDefaultMessage)
                    .collect(Collectors.toList());
            throw new ApiException(ResponseCode.PARAMETER_ERROR, String.join(";", msgs));
        }
        // 保存用户数据
    }
}

@ControllerAdvice
@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(ApiException.class)
    public ResponseData handleApiException(ApiException e) {
        return new ResponseData(e.getCode(), e.getMessage());
    }

    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseData handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
        List<String> msgs = e.getBindingResult().getAllErrors().stream()
                .map(DefaultMessageSourceResolvable::getDefaultMessage)
                .collect(Collectors.toList());
        return new ResponseData(ResponseCode.PARAMETER_ERROR, String.join(";", msgs));
    }

    @ExceptionHandler(Exception.class)
    public ResponseData handleException(Exception e) {
        return new ResponseData(ResponseCode.SERVER_ERROR);
    }
}

@Data
public class User {

    @NotBlank
    private String username;

    @NotNull
    private String password;
}

@Data
public class ResponseData {

    private int code;

    private String message;

    public ResponseData() {
        code = ResponseCode.SUCCESS;
        message = "成功";
    }

    public ResponseData(int code, String message) {
        this.code = code;
        this.message = message;
    }
}

public class ApiException extends RuntimeException {

    private int code;

    public ApiException(int code, String message) {
        super(message);
        this.code = code;
    }

    public int getCode() {
        return code;
    }
}

public class ResponseCode {

    public static final int SUCCESS = 0;

    public static final int PARAMETER_ERROR = 1001;

    public static final int SERVER_ERROR = 5001;

}

其中,用户实体类 User.java 包含了两个字段 username、password,并使用了 NotBlank、NotNull 等注解来限制它们的输入规则。Controller 中的 createUser() 方法使用了 @Valid 和 BindingResult 来实现验证和异常抛出。GlobalExceptionHandler 类中对不同类型的异常进行了处理,以及定义了异常代码。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:SpringMvc @Valid如何抛出拦截异常 - Python技术站

(0)
上一篇 2023年5月27日
下一篇 2023年5月27日

相关文章

  • Jenkins+tomcat自动发布的热部署/重启及遇到的问题解决办法(推荐)

    下面详细讲解一下“Jenkins+tomcat自动发布的热部署/重启及遇到的问题解决办法(推荐)”的完整攻略。 一、背景介绍 在我们的开发过程中,经常需要发布新的代码到服务器上。但是每次手动更新是十分繁琐的,而且还容易出错。因此我们需要一个自动化的过程来完成这个任务。Jenkins是目前最流行的自动化构建工具之一,它可以帮助我们实现自动化构建、测试、部署等任…

    Java 2023年5月20日
    00
  • SpringBoot如何使用自定义注解实现接口限流

    接下来我将详细讲解SpringBoot如何使用自定义注解实现接口限流。 一、什么是接口限流?为什么需要接口限流? 接口限流是应对高并发场景下保障系统稳定性的一种重要手段。一些接口请求过于频繁,可能会占用系统过多的资源,导致系统崩溃等问题。因此,我们需要对这些接口设置限流策略,对请求进行控制,而这种限流策略就是接口限流。 二、如何使用自定义注解实现接口限流? …

    Java 2023年5月26日
    00
  • Redis介绍和使用场景详解

    Redis介绍和使用场景详解 什么是Redis Redis是一种高性能的内存数据库,其发展史可以追溯到2009年。Redis支持多种数据结构,包括字符串、哈希表、列表、集合和有序集合,同时还支持事务、持久化和复制等功能。Redis作为一个内存数据库,它的读写速度非常快,被广泛应用在数据缓存、消息队列、计数器等场景中。 Redis的使用场景 缓存 Redis最…

    Java 2023年6月1日
    00
  • springmvc字符编码过滤器CharacterEncodingFilter的使用

    当我们使用Spring MVC开发Web应用时,可能会发现在处理请求参数时存在中文乱码的问题,这时候我们需要使用字符编码过滤器(CharacterEncodingFilter)来解决这个问题。 以下是使用Spring MVC中字符编码过滤器的步骤: 步骤一:添加依赖项 首先,在项目的pom.xml文件中添加以下依赖项: <dependency> …

    Java 2023年5月20日
    00
  • Java实现经典游戏泡泡堂的示例代码

    Java实现经典游戏泡泡堂的示例代码攻略 概述 本文将介绍如何使用Java实现经典游戏泡泡堂的示例代码。泡泡堂是一款非常受欢迎的街机游戏,同时它也是一款非常好的练习Java编程技巧的项目,包括了面向对象编程、多线程、网络编程等各种核心技术点。 准备工作 在开始编写泡泡堂代码之前,我们需要先准备一些工作: 安装Java JDK,并设置好环境变量; 选择一个合适…

    Java 2023年5月19日
    00
  • 详解前端HTML5几种存储方式的总结

    首先,需要明确的是,在前端开发中,常常需要存储数据,而HTML5提供了多种存储方式,其中包括LocalStorage、SessionStorage、IndexedDB和WebSQL。下面我们将逐一讲解这些存储方式的详细情况。 LocalStorage LocalStorage是HTML5中存储数据的一种方式,它可以将数据存储在浏览器的本地存储空间中。可以使用…

    Java 2023年6月15日
    00
  • 详解java连接mysql数据库的五种方式

    文章:详解Java连接MySQL数据库的五种方式 介绍 在Java应用中,我们经常需要连接数据库,而MySQL数据库是很受欢迎的一种关系型数据库。本文将详细介绍Java连接MySQL数据库的五种方式。 方式一:JDBC Java Database Connectivity (JDBC) 是Java平台下一项用于执行SQL语句的Java API,基本上,所有J…

    Java 2023年5月19日
    00
  • 在Intellij Idea中使用jstl标签库的方法

    使用JSTL(JSP标准标签库)可以在JSP页面中更轻松地实现一些复杂的逻辑操作,例如循环、条件判断等操作。下面是在IntelliJ IDEA中使用JSTL的方法。 步骤一:导入JSTL Jar包 在项目中引入JSTL的Jar包。可以在Maven或Gradle中配置依赖项,或者手动下载Jar包并将其添加到项目的类路径中。 以下是Maven依赖项的示例: &l…

    Java 2023年6月15日
    00
合作推广
合作推广
分享本页
返回顶部