Springboot如何优雅地进行字段校验

下面是关于如何优雅地进行字段校验的 Spring Boot 攻略。

1. 配置实体类字段校验

首先,在实体类中使用 JSR303 验证为我们提供了强大的约束形式,可通过添加适当的注释来轻松验证诸如是否为空或字符串长度是否满足要求等逻辑。

例如,下面的实体类注释了一个用户名字段,这个字段不能为空,并且长度在 6 到 16 个字符之间:

@Data
public class UserDTO {
    @NotBlank(message = "用户名不能为空!")
    @Length(min = 6, max = 16, message = "用户名长度必须在 {min} 到 {max} 个字符之间!")
    private String userName;
    ...
}

在控制器的方法中,可以通过添加 @Valid 注释来执行此实体类的验证:

@RestController
public class UserController {
    @PostMapping("/user")
    public String addUser(@Valid @RequestBody UserDTO userDTO) {
        // 验证通过
        return "success";
    }
}

这样就可以通过 Spring Boot 自带的 Validator 实现实体类字段校验了,而我们只需添加注释即可。

2. 自定义全局异常处理

当字段校验不通过时,常规的处理方式是返回带有错误信息的 HTTP 响应。但是,Spring Boot 提供了全局异常处理机制,使我们能够更简洁地组织和捕获异常,并将异常信息转换为我们需要的格式并返回给客户端。以下是实现自定义全局异常处理的步骤:

2.1 实现自定义异常

首先,需要创建一个自定义异常类,该类应继承 RuntimeException。例如:

public class GlobalException extends RuntimeException {
    private String message;

    public GlobalException(String message) {
        this.message = message;
    }

    @Override
    public String getMessage() {
        return message;
    }
}

2.2 实现 ControllerAdvice

创建一个 @ControllerAdvice 注释的类 FooExceptionHandler,并实现以下方法:

@ControllerAdvice
public class FooExceptionHandler {
    @ExceptionHandler(ConstraintViolationException.class)
    public ResponseEntity<?> handleConstraintViolationException(ConstraintViolationException e) {
        List<String> msgList = new ArrayList<>();
        e.getConstraintViolations().forEach(item -> {
            msgList.add(item.getMessage());
        });
        String msg = StringUtils.join(msgList.toArray(), ",");
        return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(msg);
    }

    @ExceptionHandler(GlobalException.class)
    public ResponseEntity<?> handleGlobalException(GlobalException e) {
        return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(e.getMessage());
    }
}

其中,handleConstraintViolationException 方法捕获 JSR303 验证异常并将错误信息合并为一个消息返回给客户端。handleGlobalException 方法则用来捕获 GlobalException 异常并返回异常信息给客户端。

2.3 测试

编写测试方法进行测试,例如:

@RestController
public class FooController {
    @RequestMapping("/foo")
    public String foo(@RequestParam("bar") String bar) {
        if (StringUtils.isBlank(bar)) {
            throw new GlobalException("参数 bar 不可为空!");
        }
        return "success";
    }
}

使用 Postman 等接口测试工具调用 /foo 接口,当bar参数为空时,会返回异常信息 Parameter 'bar' must not be empty。

示例

示例一

下面以创建一个添加用户的 API 接口为例进行演示。首先,我们通过给 UserDTO 实体类的 userName 字段添加注释来进行字段校验:

@Data
public class UserDTO {
    @NotBlank(message = "用户名不能为空!")
    @Length(min = 6, max = 16, message = "用户名长度必须在 {min} 到 {max} 个字符之间!")
    private String userName;
    ...
}

然后,在创建用户的 Controller 方法 addUser 中添加 @Valid 注释,调用此方法时,Spring Boot 将自动执行 UserDTO 的验证:

@RestController
public class UserController {
    @PostMapping("/user")
    public String addUser(@Valid @RequestBody UserDTO userDTO) {
        // 验证通过
        return "success";
    }
}

示例二

第二个示例将通过自定义全局异常处理来演示优雅的异常处理。

在演示中,将创建一个 /foo 请求,其参数 bar 必须存在,否则将会抛出 GlobalException 异常,然后 GlobalExceptionHandler 将捕获此异常并返回给客户端。以下是实现代码:

@ControllerAdvice
public class FooExceptionHandler {
    @ExceptionHandler(GlobalException.class)
    public ResponseEntity<?> handleGlobalException(GlobalException e) {
        return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(e.getMessage());
    }
}

@RestController
public class FooController {
    @RequestMapping("/foo")
    public String foo(@RequestParam("bar") String bar) {
        if (StringUtils.isBlank(bar)) {
            throw new GlobalException("参数 bar 不可为空!");
        }
        return "success";
    }
}

public class GlobalException extends RuntimeException {
    private String message;

    public GlobalException(String message) {
        this.message = message;
    }

    @Override
    public String getMessage() {
        return message;
    }
}

在以上代码中,我们创建了一个 GlobalException 异常类,并在 FooController 的 foo 方法中抛出此异常。最后,我们使用 @ControllerAdvice 注释的全局异常处理器 FooExceptionHandler 捕获此异常并返回给客户端。

以上就是 Spring Boot 中优雅字段校验和异常处理的攻略,他们能够节省大量的代码处理时间,提高代码的可读性和可维护性。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Springboot如何优雅地进行字段校验 - Python技术站

(0)
上一篇 2023年6月25日
下一篇 2023年6月25日

相关文章

  • teamviewer一直显示初始化参数该怎么办?

    如果TeamViewer一直显示初始化参数,可以按照以下步骤来解决此问题: 1. 更新TeamViewer 首先,我们需要确保使用的TeamViewer版本是最新的。下载并安装最新的TeamViewer版本,可能会修复此问题。 2. 重启TeamViewer服务 如果更新后问题仍未解决,我们可以尝试重启TeamViewer服务。按照以下步骤执行: 按下Win…

    other 2023年6月20日
    00
  • Win10虚拟内存怎么设置?Win10设置虚拟内存的方法

    Win10虚拟内存设置攻略 什么是虚拟内存? 虚拟内存是计算机系统中的一种技术,它允许操作系统将部分硬盘空间用作内存扩展,以便处理大量的数据和程序。在Windows 10中,你可以手动设置虚拟内存的大小和位置。 设置虚拟内存的步骤 以下是在Windows 10中设置虚拟内存的步骤: 打开“控制面板”:点击开始菜单,然后在搜索栏中输入“控制面板”,并选择打开它…

    other 2023年8月1日
    00
  • X86是32位还是64位 X86和X64含义介绍

    X86是32位还是64位 X86是一种处理器架构,最初设计为32位,但后来也发展出了64位版本。下面将详细介绍X86的32位和64位版本以及它们的含义。 X86-32(32位) X86-32是指32位的X86处理器架构。它最早出现在Intel 80386处理器上,因此得名。X86-32处理器具有以下特点: 寻址空间:32位处理器可以寻址2^32(4GB)的内…

    other 2023年7月28日
    00
  • php魔术方法与魔术变量、内置方法与内置变量的深入分析

    PHP魔术方法与魔术变量、内置方法与内置变量的深入分析攻略 1. 魔术方法与魔术变量 1.1 魔术方法 在PHP中,魔术方法是一组特殊的方法,它们以双下划线(__)开头和结尾。这些方法在特定的情况下会被自动调用,用于实现一些特定的功能。以下是一些常用的魔术方法: __construct(): 当一个对象被创建时自动调用的构造方法。 __destruct():…

    other 2023年8月8日
    00
  • WPF自定义路由事件的实例教程

    WPF自定义路由事件的实例教程 什么是WPF自定义路由事件 在WPF中,路由事件是一种事件路由方式,它可以让事件沿着逻辑树传递,从而到达触发事件的元素树的根目录。相比起普通的事件,路由事件具有更强大的扩展性。 WPF自定义路由事件就是利用路由事件机制,创建一个自定义的路由事件。 自定义路由事件的步骤 第一步:创建自定义路由事件的类 首先,我们需要创建一个继承…

    other 2023年6月25日
    00
  • Android Studio中统一管理版本号引用配置问题

    Android Studio中统一管理版本号引用配置问题攻略 在Android开发中,版本号是一个重要的概念,用于标识应用程序的不同版本。在Android Studio中,我们可以通过统一管理版本号引用配置来简化版本号的管理过程。下面是一个详细的攻略,包含了两个示例说明。 步骤一:创建版本号引用配置文件 在项目的根目录下创建一个名为version.gradl…

    other 2023年8月2日
    00
  • Vue-cli@3.0 插件系统简析

    Vue-cli@3.0 插件系统简析 Vue-cli@3.0是Vue.js官方提供的脚手架工具,能够帮助我们快速创建Vue.js项目,提供了丰富的配置选项和插件扩展能力。本文主要介绍Vue-cli@3.0的插件系统,让我们能够更好的了解和使用Vue-cli@3.0。 Vue-cli@3.0 插件系统简介 Vue-cli@3.0的插件系统是基于Plugin A…

    other 2023年6月27日
    00
  • Linux du命令查看文件夹大小并按降序排列

    当我们需要查看Linux系统中文件夹的大小并按照一定顺序进行排列时,可以使用du命令。du即“Disk Usage”的缩写,能够查看文件或目录所占磁盘空间大小。 以下是Linux du命令查看文件夹大小并按降序排列的完整攻略: 语法 du [-abcdfhHiklmnsSvxX] [–block-size=SIZE] [–exclude=PATTERN]…

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