@validated和@valid的区别和作用

一、基本作用

  • @Valid

    • @Valid 是 Java 标准 JSR 380(Bean Validation 2.0)规范中的注解,主要用于标记一个对象的属性需要进行验证。
    • 当应用于方法参数时,它会触发对该参数对象的属性的验证。通常用于验证嵌套对象和集合元素。
    • 它会递归地对对象的属性进行验证,如果属性是对象或集合,会继续对其内部元素进行验证。
  • @Validated

    • @Validated 是 Spring 框架特有的注解,它扩展了 @Valid 的功能。
    • 除了支持 @Valid 的基本验证功能外,它还提供了额外的功能,例如分组验证和方法级别的验证。

二、分组验证

  • @Validated

支持分组验证,可以根据不同的验证组来应用不同的验证规则。

可以在验证注解(如 @NotNull@Size 等)上指定 groups 属性,将验证规则划分为不同的组。

  • import javax.validation.constraints.NotEmpty;
    import javax.validation.constraints.Size;
    import javax.validation.groups.Default;
    
    public class User {
        @NotEmpty(groups = FirstGroup.class)
        private String firstname;
    
        @NotEmpty(groups = SecondGroup.class)
        private String lastname;
    
        @Size(min = 1, max = 50, groups = Default.class)
        private String email;
    
        // Getter 和 Setter 方法
    }

    在上述代码中,User 类的属性使用了不同的验证组,如 FirstGroup 和 SecondGroup。可以在控制器中使用 @Validated 来指定使用哪个组进行验证:

    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 UserController {
        @PostMapping("/users")
        public void createUser(@Validated({FirstGroup.class}) @RequestBody User user) {
            // 处理用户创建逻辑
        }
    }

    这里,只有 firstname 属性会被验证,因为我们在 @Validated 中指定了 FirstGroup 组。

三、方法级别的验证

  • @Validated

可以应用于方法级别,对方法的返回值或方法参数进行验证。

例如,可以使用 @Validated 对服务层方法的返回值进行验证:

import org.springframework.validation.annotation.Validated;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.util.List;

@Validated
public interface UserService {
    @NotNull
    List<User> getUsers();
}

在这个例子中,@Validated 注解应用于服务接口,@NotNull 注解用于确保 getUsers() 方法的返回值不为 null

四、使用场景

  • @Valid

通常用于简单的参数验证,尤其是在 Java EE 环境或不使用 Spring 框架的情况下。

适用于验证对象及其嵌套对象和集合元素,确保它们符合 Java Bean Validation 规范中的约束。

例如,在使用 JPA 时,确保实体类的属性满足一定的约束,在持久化之前进行验证。

  • @Validated

在 Spring 框架中使用,尤其是在 Spring MVC 控制器和服务层。

当需要进行分组验证或方法级别的验证时,使用 @Validated

当使用 Spring 框架的 @RequestBody 接收请求体并需要对其进行验证时,通常会使用 @Validated 或 @Valid,但 @Validated 提供了更多的灵活性,特别是对于复杂的业务逻辑验证。

五、异常处理

当使用 @Valid 或 @Validated 进行验证时,如果验证失败,会抛出相应的异常:

javax.validation.ConstraintViolationException:在 Java EE 环境或不使用 Spring 的情况下,通常会抛出此异常。

org.springframework.web.bind.MethodArgumentNotValidException:在 Spring MVC 中,会抛出此异常。

可以使用异常处理机制来处理这些异常,例如在 Spring 中:

import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import java.util.HashMap;
import java.util.Map;

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

总结

  • @Valid 是 Java 标准的验证注解,用于对象属性的基本验证。
  • @Validated 是 Spring 特有的注解,提供了分组验证和方法级别的验证功能,在 Spring 框架中使用更灵活,适用于更复杂的验证场景。
Java中`@Validated``@Valid`在多个方面存在区别: - **所属包与来源**:`@Valid`所属包为`javax.validation.Valid`,是JSR - 303规范(Bean Validation API)的一部分,由Hibernate Validator等实现;`@Validated`包位置是`org.springframework.validation.annotation`,是`@Valid`的一次封装,由Spring提供校验机制使用 [^1][^2][^3]。 - **与Spring框架集成度**:`@Valid`可以在任何层使用,但与Spring框架的集成不是最紧密的,特别是在组级别的校验上;`@Validated`是Spring特有的验证注解,与Spring框架集成紧密,更适合Spring环境 [^2][^5]。 - **分组校验支持**:`@Valid`不支持分组校验;`@Validated`的主要优势在于支持验证分组,允许给验证分组,灵活地控制哪些验证规则在何时触发,例如在用户注册更新资料时可使用不同的验证规则 [^5]。 - **使用场景**:在检验Controller的入参是否符合规范时,使用`@Validated`或者`@Valid`都可以实现,但使用`@Validated`更利于做扩展功能。在需要分组验证,即不同情况下使用不同验证规则时,`@Validated`是合适的选择 [^3][^4][^5]。 示例代码展示在Controller中使用`@Validated``@Valid`校验入参: ```java 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; class RegisterVo { // 假设这里有需要校验的属性 } class JSONResult { public static JSONResult error() { return new JSONResult(); } public JSONResult message(String message) { return this; } public static JSONResult ok() { return new JSONResult(); } } class MemberService { public void register(RegisterVo registerVo) { // 注册逻辑 } } @RestController public class MemberController { private MemberService memberService = new MemberService(); @PostMapping("register") // @Valid这两个用哪个效果都一样 public JSONResult register(@Validated @RequestBody RegisterVo registerVo, BindingResult bindingResult) { // 会把校验失败情况下的反馈信息 if (bindingResult.hasErrors()) { System.out.println(bindingResult.getFieldError().getDefaultMessage()); return JSONResult.error().message(bindingResult.getFieldError().getDefaultMessage()); } memberService.register(registerVo); return JSONResult.ok(); } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小小懒懒

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值