开发者

SpringBoot使用spring-boot-starter-validation实现参数校验

目录
  • 前言
  • 一、什么是 spring-boot-starter-validation
    • 定义
    • 特性
  • 二、快速入门:引入与使用
    • Step 1:添加依赖
    • Step 2:定义请求对象并添加校验注解
    • Step 3:在 Controller 中启用校验
  • 三、实战:全局异常统一处理
    •  四、高级用法详解
      • 1. 嵌套对象校验
      • 2. 分组校验(Group Validation)
      • 3. 自定义校验规则
    • 五、国际化支持(i18n)
      • 六、常见问题与解决方案
        • 七、总结对比表
          •  八、结语

            前言

            在开发 RESTful 接口时,接口参数校验是保障系统健壮性和安全性的重要一环。Spring Boot 提供了对 Bean Validation 的开箱即用支持 —— 通过 spring-boot-starter-validation 模块,我们可以非常方便地使用 jsR-380 标准定义的注解(如 @NotNull@NotBlank@Email 等)进行参数校验。

            本文将带你从零开始掌握如何在 Spring Boot 中使用 spring-boot-starter-validation,并通过多个实际案例演示其强大功能,包括:

            • 单个参数校验
            • 对象嵌套校验
            • 自定义校验规则
            • 全局异常统一处理
            • 多语言错误信息支持

            无论你是初学者,还是有一定经验的开发者,这篇文章都能让你写出更规范、更健壮的接口!

            一、什么是 spring-boot-starter-validation

            定义

            spring-boot-starter-validation 是 Spring Boot 提供的一个 starter 模块,它默认集成了 Hibernate Validator,实现了 Java 的 Bean Validation 规范(JSR-380),可以用于对 Java Bean 的字段进行自动校验。

            特性

            特性描述
            零配置默认集成 Hibernate Validator
            注解驱动支持 @NotNull, @Size, @Email 等丰富注解
            分组校验可以根据业务场景分组验证
            异常统一处理结合 @ControllerAdvice 统一处理校验失败
            多语言支持支持国际化错误提示

            二、快速入门:引入与使用

            Step 1:添加依赖

            如果你创建的是一个标准的 Spring Boot Web 项目,spring-boot-starter-web 已经默认包含了 spring-boot-starter-validation,无需额外添加。

            <!-- 如果你想显式添加 -->
            http://www.devze.com<dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-validation</artifactId>
            </dependency>
            

            Step 2:定义请求对象并添加校验注解

            import javax.validation.constraintsjavascript.*;
            
            public class UserRequest {
            
                @NotBlank(message = "用户名不能为空")
                private String username;
            
                @Email(message = "邮箱格式不正确")
                private String email;
            
                @Min(value = 18, message = "年龄不能小于18岁")
                @Max(value = 120, message = "年龄不能大于120岁")
                private int age;
            
                // getters and setters...
            }
            

            Step 3:在 Controller 中启用校验

            在 Controller 方法中,使用 @Valid 注解开启校验逻辑,并结合 @RequestBody 使用。

            @RestController
            @RequestMapping("/users")
            public class UserController {
            
                @PostMapping
                public String createUser(@Valid @RequestBody UserRequest request) {
                    return "用户提交成功:" + request.toString();
                }
            }
            

            注意:

            • @Valid 必须写在方法参数上;
            • 如果校验失败,会抛出 MethodArgumentNotValidException 异常;

            三、实战:全局异常统一处理

            为了统一返回错误信息,我们可以使用 @ControllerAdvice 来捕获所有校验异常。

            示例代码:

            @ControllerAdvice
            public class GlobalValidationHandler {
            
                @ResponseStatus(HttpStatus.BAD_REQUEST)
                @ExceptionHandler(MethodArgumentNotValidException.class)
                public Map<String, String> handleValidationExceptions(MethodArgumentNotValidException ex) {
                    Map<String, String> errors = new HashMap<>();
                    ex.getBindingResult().getAllErrors().forEach((error) -python> {
                        String fieldName = ((org.springframework.validation.FieldError) error).getField();
                        String errorMessage = error.getDefaultMessage();
                        errors.put(fieldName, errorMessage);
                    });
                    return errors;
                }
            }
            

            返回示例:

            {
              "username": "用户名不能为空",
              "email": "邮箱格式不正确"
            }
            

             四、高级用法详解

            1. 嵌套对象校验

            你可以对嵌套的对象也进行校验:

            public class AddressRequest {
                @NotBlank(message = "地址不能为空")
                private String detail;
                // getter/setter
            }
            
            public class UserRequest {
                @NotBlank(message = "用户名不能为空")
                private String username;
            
                @NotNull(message = "地址信息不能为空")
                private AddressRequest address;
                // getter/setter
            }
            

            只要加上 @Valid 注解,Spring 会自动递归校验嵌套对象。

            2. 分组校验(Group Validation)

            有时候你希望同一个对象在不同接口中使用不同的校验规则?这时就可以使用分组校验。

            第一步:定义分组接口

            public interface OnCreate {}
            public interface OnUpdate {}
            

            第二步:在实体类中指定分组

            public class UserRequest {
            
                @NotBlank(groups = OnCreate.class, message = "创建时用户名不能为空")
                @NotBlank(groups = OnUpdate.class, message = "更新时用户名不能为空")
                private String username;
            
                @NotBlank(groups = OnCreate.class,WalEdIHg message = "邮箱不能为空")
                private String email;
            }
            

            第三步:在 Controller 中指定分组

            @PostMapping("/create")
            public String createUser(@Validated(OnCreate.class) @RequestBody UserRequest request) {
                return "创建用户";
            }
            
            @PostMapping("/update")
            public String updateUser(@Validated(OnUpdate.class) @RequestBody UserRequest request) {
                return "更新用户";
            }
            

            注意:此时必须使用 @Validated 注解(来自 org.springframework.validation.annotation.Validated),而非 @Valid

            3. 自定义校验规则

            当内置注解不能满足需求时,可以自定义校验器。

            步骤如下:

            Step 1:创建注解

            @Target({ ElementType.FIELD })
            @Retention(RetentionPolicy.RUNTIME)
            @Constraint(validatedBy = MobileValidator.class)
            public @interface Mobile {
                String message() default "手机号格式不正确";
                Class<?>[] groups() default {};
                Class<? extends Payload>[] payload() default {};
            }
            

            Step 2:实现校验器

            public class MobileValidator implements ConstraintV编程客栈alidator<Mobile, String> {
            
                private static final String MOBILE_REGEX = "^1[3-9]\\d{9}$";
            
                @Override
                public boolean isValid(String value, ConstraintValidatorContext context) {
                    return value != null && value.matches(MOBILE_REGEX);
                }
            }
            

            Step 3:使用注解

            @Mobile(message = "手机号格式错误")
            private String mobile;
            

            五、国际化支持(i18n)

            你可以为不同语言提供不同的错误提示信息:

            messages.properties 文件中定义:

            NotBlank.userRequest.username=用户名不能为空
            Mobile.userRequest.mobile=手机号格式错误
            

            再配合 Spring 的 MessageSourceLocaleResolver,即可实现多语言错误提示。

            六、常见问题与解决方案

            问题解决方案
            校验不生效确保使用 @Valid 或 @Validated
            嵌套对象未校验确保子对象字段也加了注解
            分组无效确保使用 @Validated 并指定分组
            错误信息乱码设置响应编码或使用 JSON 序列化
            无法获取字段名使用 FieldError 获取具体字段

            七、总结对比表

            功能描述
            校验方式注解驱动,声明式校验
            异常处理@ControllerAdvice 统一处理
            嵌套对象支持递归校验
            分组校验支持按业务场景定制
            自定义规则支持自定义注解和校验器
            国际化支持多语言提示

             八、结语

            Spring Boot 提供的 spring-boot-starter-validation 模块极大简化了接口参数校验的开发流程,使得我们能够以最小的成本写出安全、规范、可维护性强的接口代码。

            无论是构建企业级后台系统,还是搭建高并发 API 平台,都应该合理使用参数校验来提升系统的稳定性与用户体验。

            到此这篇关于SpringBoot使用spring-boot-starter-validation实现参数校验的文章就介绍到这了,更多相关SpringBoot参数校验内容请搜索编程客栈(www.devze.com)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程客栈(www.devze.com)!

            0

            上一篇:

            下一篇:

            精彩评论

            暂无评论...
            验证码 换一张
            取 消

            最新开发

            开发排行榜