Spring Validation 校验 ( 二 )

4. 分组验证

Bean Validation 支持分组验证,这允许您根据不同的业务场景来定义不同的验证规则。

  • @Validated(group) : 用于控制器方法参数,指定一组验证规则。

  • @GroupSequence(groups) : 指定验证的顺序。

4.1.定义分组

下面是一个使用分组验证的示例:

java 复制代码
import jakarta.validation.groups.Default;

public interface UserGroups {
    interface Registration extends Default {}
    interface Login extends Default {}
}

4.2.设置验证规则

java 复制代码
import com.yuan.springvalidationdemo.valid.UserGroups;
import jakarta.validation.GroupSequence;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;

@GroupSequence({UserGroups.Registration.class, UserGroups.Login.class})
public class User2 {
    @NotBlank(groups = UserGroups.Registration.class, message = "用户名在注册时不能为空")
    @Size(min = 5, max = 20, groups = {UserGroups.Registration.class, UserGroups.Login.class}, message = "用户名长度应在5到20个字符之间")
    private String username;

    @NotBlank(groups = UserGroups.Registration.class, message = "密码在注册时不能为空")
    @Size(min = 8, max = 32, groups = {UserGroups.Registration.class, UserGroups.Login.class}, message = "密码长度应在8到32个字符之间")
    private String password;

    @Email(groups = UserGroups.Registration.class, message = "邮箱格式不正确")
    private String email;
    
    // 构造函数、getter 和 setter 省略
}

在这个示例中,User2 类定义了两个验证组:Registration 和 Login。username 和 password 字段分别在不同的组中有不同的验证规则。当验证用户注册时,Registration 组的规则会被应用;当验证用户登录时,Login 组的规则会被应用。

4.3.Controller

java 复制代码
import com.yuan.springvalidationdemo.domain.User2;
import com.yuan.springvalidationdemo.valid.UserGroups;

import jakarta.validation.Valid;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;



@RestController
public class UserController3 {

    @PostMapping("/register3")
    public ResponseEntity<String> register(@Valid @RequestBody User2 user, BindingResult result) {
        if (result.hasErrors()) {
            // 如果有验证错误,则返回错误信息
            StringBuilder errorMessage = new StringBuilder();
            result.getFieldErrors().forEach(error -> {
                errorMessage.append(error.getDefaultMessage()).append("\n");
            });
            return ResponseEntity.badRequest().body(errorMessage.toString());
        }

        // 保存用户
        return ResponseEntity.ok("注册成功");
    }

    @PostMapping("/login3")
    @Validated({UserGroups.Login.class})
    public ResponseEntity<String> login(@Valid @RequestBody User2 user, BindingResult result) {
        if (result.hasErrors()) {
            // 如果有验证错误,则返回错误信息
            StringBuilder errorMessage = new StringBuilder();
            result.getFieldErrors().forEach(error -> {
                errorMessage.append(error.getDefaultMessage()).append("\n");
            });
            return ResponseEntity.badRequest().body(errorMessage.toString());
        }

        // 登录逻辑
        return ResponseEntity.ok("登录成功");
    }
}

通过 @Validated({UserGroups.Login.class}) 指定验证 分组规则

5. 自定义注解

可以创建自定义注解来定义特定的验证逻辑。

  • @Constraint(validatedBy = MyValidator.class) : 定义自定义注解时使用,指定自定义验证器类。

5.1. 定义验证注解

java 复制代码
import jakarta.validation.Constraint;
import jakarta.validation.Payload;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = UniqueUsernameValidator.class)
@Documented
public @interface UniqueUsername {

    String message() default "用户名必须唯一";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};
}

5.2. 实现自定义验证器

java 复制代码
import com.yuan.springvalidationdemo.service.impl.UserServiceImpl;
import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class UniqueUsernameValidator implements ConstraintValidator<UniqueUsername, String> {

    @Autowired
    private UserServiceImpl userService;

    @Override
    public boolean isValid(String username, ConstraintValidatorContext context) {
        return !userService.existsByUsername(username);
    }

5.3. 使用注解

java 复制代码
import com.yuan.springvalidationdemo.valid.UniqueUsername;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;

public class User3 {

    @NotBlank(message = "用户名不能为空")
    @Size(min = 5, max = 20, message = "用户名长度应在5到20个字符之间")
    @UniqueUsername
    private String username;

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

      // 构造函数、getter 和 setter 省略
}
相关推荐
明月_清风3 小时前
Muse 登顶 App Store 第一,SDK 直接开源:AI Agent 开始进入下一个阶段
人工智能·后端
leikooo3 小时前
用餐厅和盘子理解栈和堆
java·数据结构·链表·rust
Ivanqhz4 小时前
激活函数在 Transformer 中的作用及各种变体简述
java·linux·数据库·人工智能·深度学习
沙漠之主5 小时前
C++编程教学设计资料:从入门到实战的完整课程方案
java·前端·c++
FPGA小徐5 小时前
PA1 基础设施(2)深度解析:NEMU 中 ITRACE、MTRACE、FTRACE、IRINGBUF、ETRACE、DIFFTEST 全解析
java·服务器·网络
YOLO数据集集合5 小时前
EvoAgent:面向PR研发治理的自进化Multi-Agent Harness系统
java·开发语言·目标检测·agent·自进化
hsfxuebao6 小时前
Loop Engineering 保姆级教程 + 项目实战
人工智能·后端
知行EDI6 小时前
知行之桥 MaBang 端口使用指南——Create Order 订单创建篇
java·服务器·数据库
笑鸿的学习笔记6 小时前
C++笔记之大块顺序写
java·c++·笔记
打工仔折腾 AI6 小时前
从 Demo 到生产级 Agent:8 个关键设计机制与 Python 实现拆解
java·jvm·人工智能·后端·python·langchain·ai agent 实战