一、基本作用:
-
@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 框架中使用更灵活,适用于更复杂的验证场景。