SpringMvc @Valid如何抛出拦截异常

yizhihongxing

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日

相关文章

  • Android笔记之:App模块化及工程扩展的应用

    以下是对“Android笔记之:App模块化及工程扩展的应用”攻略的详细讲解。 1. 什么是App模块化? App模块化是指将整个应用程序拆分为多个独立的模块,每个模块只包含特定的功能。这样做有助于提高代码的可重用性和维护性,并且可以最大程度地减少不必要的耦合。 2. 怎么进行App模块化? 进行App模块化有两种方法:一种是动态模块化,一种是静态模块化。 …

    Java 2023年6月1日
    00
  • SpringBoot实现WEB的常用功能案例详解

    Spring Boot是一个快速构建应用程序的框架,它提供了许多常用的Web功能,如路由、过滤器、拦截器、异常处理等。以下是Spring Boot实现Web的常用功能的完整攻略: 路由 路由是Web应用程序中的一个重要功能,它可以将请求映射到相应的处理程序。在Spring Boot中,我们可以使用@Controller和@RequestMapping注解来定…

    Java 2023年5月15日
    00
  • Java C++题解leetcode字符串轮转KMP算法详解

    Java C++题解leetcode字符串轮转KMP算法详解 1. 题目描述 给定两个字符串s1和s2,判断s2是否可以通过将s1中的某个子串移动后得到。 2. 思路分析 2.1 暴力枚举 我们可以将s1分为两段,任选一段放到另一段的前面,再判断是否与s2相等,如此循环往复。但是这样的时间复杂度为$O(n^2)$。 2.2 KMP算法 我们可以利用KMP算法…

    Java 2023年5月19日
    00
  • java使用JDBC连接数据库的五种方式(IDEA版)

    下面是对“Java使用JDBC连接数据库的五种方式(IDEA版)”的完整攻略: 一、使用JDBC连接数据库的五种方式 1.1 方式一:使用Class.forName方式连接 使用Class.forName方式连接数据库需要导入jdbc驱动jar包,代码示例: // 加载MySql数据库驱动程序 Class.forName("com.mysql.jd…

    Java 2023年5月19日
    00
  • java实现俄罗斯方块小程序

    下面是详细讲解“java实现俄罗斯方块小程序”的完整攻略。 准备工作 首先,需要安装JDK和Eclipse开发工具,同时需要掌握Java编程语言的基本语法和面向对象编程的思想。 实现思路 设计游戏界面,包括游戏区域、方块、游戏分数等; 实现方块的下落和旋转功能,要考虑边界判断和碰撞检测; 实现方块的消除功能,判断整行是否满了; 实现游戏结束判断功能。 具体步…

    Java 2023年5月23日
    00
  • javaScript 连接打印机,打印小票的实例

    要实现 JavaScript 连接打印机,打印小票的功能,可以借助 JavaScript 打印插件JSPrintManager。 JSPrintManager 是一个完全跨平台和打印技术无关的 JavaScript 打印客户端(打印机驱动程序),可通过扩展 Web 端点管理打印机及其设置,生成和打印 ZPL、EPL、ESC/POS、HTML、PDF、PNG、…

    Java 2023年6月15日
    00
  • Spring Boot2.0 @ConfigurationProperties使用详解

    下面是“Spring Boot2.0 @ConfigurationProperties使用详解”的完整攻略。 简介 在Spring Boot应用中,常常需要使用到大量的配置属性。为了提高可维护性,Spring Boot提供了@ConfigurationProperties注解,允许开发者将配置属性注入到Java Bean中,并进行统一管理。 @Configu…

    Java 2023年5月31日
    00
  • 23基于java教师科研项目管理系统

    背景及意义 目前许多人仍将传统的纸质工具作为信息管理的主要工具,而网络技术的应用只是起到辅助作用。在对网络工具的认知程度上,较为传统的office软件等仍是人们使用的主要工具,而相对全面且专业的信息管理软件仍没有得到大多数人的了解或认可。本选题则旨在通过标签分类管理等方式,实现教研的各种功能,从而达到对科研管理系统的管理。 项目环境 > 前端:html…

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