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

yizhihongxing

下面是关于如何优雅地进行字段校验的 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日

相关文章

  • 实现一个简单的虚拟DOM

    实现一个简单的虚拟DOM 虚拟DOM是前端开发中常用的一种技术,它可以提高页面渲染的效率,减少DOM操作的次数。本文将提供一个完整的攻略,包括虚拟DOM的基本原理、实现方法和两个示例说明。 基本原理 虚拟DOM的基本原理是将页面的DOM结构抽象成一个JavaScript对象,称为虚拟DOM。当页面需要更新时,先对虚拟DOM进行操作,然后将虚拟DOM与页面的实…

    other 2023年5月5日
    00
  • Windows XP中获取未使用IP地址方法

    Windows XP中获取未使用IP地址方法攻略 介绍 在Windows XP操作系统中,获取未使用的IP地址可以通过以下步骤完成。这些步骤将帮助您找到可用的IP地址,以便在网络中分配给其他设备。 步骤 打开命令提示符 单击“开始”按钮,选择“运行”。 在运行对话框中,输入“cmd”并按下回车键,以打开命令提示符窗口。 使用IPConfig命令查看当前网络配…

    other 2023年7月30日
    00
  • Android使用ViewPager实现无限滑动效果

    Android使用ViewPager实现无限滑动效果攻略 在Android开发中,ViewPager是一个常用的控件,用于实现滑动切换不同的页面。然而,默认情况下,ViewPager只能滑动到最后一页或第一页,无法实现无限滑动效果。本攻略将详细介绍如何使用ViewPager实现无限滑动效果,并提供两个示例说明。 步骤一:导入依赖库 首先,在项目的build.…

    other 2023年9月6日
    00
  • Java Socket编程实例(五)- NIO UDP实践

    介绍 本文是“Java Socket编程实例”系列的第五篇,将介绍Java NIO中的UDP(User Datagram Protocol)实践。UDP是一种面向无连接的协议,常用于高速传输数据、广播和流媒体等场景。相比于TCP,UDP的特点是传输速度快、没有连接建立和断开的过程,但是可靠性差,无法保证数据传输的顺序和正确性。 在本文中,我们将使用Java …

    other 2023年6月27日
    00
  • amd锐龙处理器5怎么样 AMD锐龙Ryzen5 1600X全面深度评测

    很抱歉,由于我是一个文本模型,无法以标准的markdown格式回答您的问题。但是,我可以为您提供一份详细的攻略,包含AMD锐龙处理器5 1600X的全面深度评测,并提供两个示例说明。 AMD锐龙处理器5 1600X全面深度评测 1. 性能表现 AMD锐龙处理器5 1600X是一款六核心十二线程的处理器,采用Zen架构。它具有较高的性能表现,在多线程任务和游戏…

    other 2023年10月17日
    00
  • 通过OpenGL ES混合模式缩放视频缓冲区来适应显示尺寸

    实现视频缩放的基本思路是通过改变渲染纹理的顶点坐标和纹理坐标实现,其中OpenGL ES混合模式是一种可以较好地适应不同尺寸的方法。 具体实现方法如下: 初始化OpenGL ES环境,通过GLSurfaceView.Renderer的回调函数onSurfaceCreated实现。 @Override public void onSurfaceCreated(…

    other 2023年6月20日
    00
  • Win7系统如何自定义“开始”菜单内容?DIY“开始”菜单图文教程

    Win7系统的“开始”菜单是我们使用电脑时经常需要点击的一个入口,但是默认情况下它的内容可能并不符合我们的个人需求,那么我们可以进行一定程度的自定义来满足我们的需求。 下面是具体操作步骤: 1. 打开开始菜单文件夹 首先打开运行窗口,可以通过“Win+R”组合键打开运行窗口,或者通过点击开始菜单中的“开始搜索”框,在其中输入“shell:start menu…

    other 2023年6月25日
    00
  • 一篇文章带你了解JavaSE的数据类型

    一篇文章带你了解JavaSE的数据类型 介绍 Java是一种面向对象的编程语言,它提供了丰富的数据类型来存储和操作数据。本文将带你了解JavaSE中常见的数据类型,包括基本数据类型和引用数据类型。 基本数据类型 JavaSE中有8种基本数据类型,它们分别是: byte:用于表示整数,占用1个字节,取值范围为-128到127。 short:用于表示整数,占用2…

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