在 Spring 相关的开发中,@NotEmpty
并非 Spring 框架直接提供的注解,而是 JSR-303(Bean Validation 1.0)和 JSR-349(Bean Validation 1.1)规范中定义的注解,在 Spring 项目里,通常借助 Hibernate Validator 这个实现来使用它。下面为你详细介绍 @NotEmpty
注解:
注解作用
@NotEmpty
注解主要用于验证字符串、集合、数组或者 Map
等是否为空。具体来说:
- 对于字符串,它会检查字符串是否不为
null
且长度大于 0,即字符串不能为null
也不能是空白字符串。 - 对于集合(如
List
、Set
等)、数组以及Map
,它会检查其是否不为null
且元素数量大于 0。
依赖引入
若要在 Spring Boot 项目里使用 @NotEmpty
注解,需添加相应的依赖。在 Maven 项目中,可在 pom.xml
里添加如下依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
使用示例
以下是一个简单的 Spring Boot 示例,展示了 @NotEmpty
注解的使用:
java
import javax.validation.constraints.NotEmpty;
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 User {
@NotEmpty(message = "用户名不能为空")
private String username;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
}
@RestController
@Validated
public class UserController {
@PostMapping("/users")
public String createUser(@RequestBody @Validated User user) {
return "User created: " + user.getUsername();
}
}
代码解释
User
类:在User
类的username
字段上添加了@NotEmpty
注解,同时设置了错误提示信息"用户名不能为空"
。这意味着在对User
对象进行验证时,如果username
字段为空,就会触发验证错误,并返回该提示信息。UserController
类:该类被@Validated
注解标记,表明它需要进行验证。在createUser
方法中,@RequestBody
注解用于接收请求体中的 JSON 数据,并将其转换为User
对象,@Validated
注解则用于对User
对象进行验证。
验证结果处理
当验证不通过时,Spring 会抛出 MethodArgumentNotValidException
异常。你可以通过全局异常处理器来捕获该异常,并返回合适的错误信息给客户端。示例如下:
java
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import java.util.HashMap;
import java.util.Map;
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<Map<String, String>> handleValidationExceptions(
MethodArgumentNotValidException ex) {
BindingResult bindingResult = ex.getBindingResult();
Map<String, String> errors = new HashMap<>();
for (FieldError fieldError : bindingResult.getFieldErrors()) {
errors.put(fieldError.getField(), fieldError.getDefaultMessage());
}
return new ResponseEntity<>(errors, HttpStatus.BAD_REQUEST);
}
}
在这个全局异常处理器中,handleValidationExceptions
方法会捕获 MethodArgumentNotValidException
异常,并将验证错误信息封装成一个 Map
对象返回给客户端,同时返回 HTTP 状态码 400(Bad Request)。
@Valid 注解 跟 @Validated 对比
@Valid
和 @Validated
都用于在 Java 中进行数据验证,特别是在 Spring 框架里处理表单或请求参数验证时较为常用。不过它们存在一些差异,下面从来源、使用范围、分组验证支持、嵌套验证等方面进行对比:
来源
@Valid
:是 Java Bean Validation(JSR 303 和 JSR 349)规范的一部分,这意味着只要使用了遵循该规范的验证框架(如 Hibernate Validator),就可以使用@Valid
注解。@Validated
:是 Spring 框架提供的注解,是对 JSR-303 的@Valid
的扩展。
使用范围
@Valid
:可以用在方法、构造函数、字段、参数等上面。例如,在 Java Bean 的字段上使用@Valid
可以对该字段进行验证;在方法参数上使用可以对传入的参数对象进行验证。
java
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
public class User {
@NotNull
private String name;
// getter 和 setter 方法
}
public class Service {
public void processUser(@Valid User user) {
// 处理用户逻辑
}
}
@Validated
:主要用在类和方法上。当用于类时,表明该类需要进行验证;用于方法时,会对方法的参数进行验证。
java
import org.springframework.validation.annotation.Validated;
import javax.validation.constraints.NotNull;
@Validated
public class UserService {
public void createUser(@NotNull String username) {
// 创建用户逻辑
}
}
分组验证支持
@Valid
:本身不支持分组验证。分组验证是指可以根据不同的业务场景对不同的验证规则进行分组,然后只对特定组的规则进行验证。@Validated
:支持分组验证。可以通过指定分组的方式,让验证器只验证特定组的规则。
java
import org.springframework.validation.annotation.Validated;
import javax.validation.constraints.NotNull;
interface CreateGroup {}
interface UpdateGroup {}
@Validated
public class UserService {
public void createUser(@Validated(CreateGroup.class) User user) {
// 创建用户逻辑
}
public void updateUser(@Validated(UpdateGroup.class) User user) {
// 更新用户逻辑
}
}
class User {
@NotNull(groups = {CreateGroup.class})
private String name;
// getter 和 setter 方法
}
在上述例子中,createUser
方法只对 CreateGroup
组的验证规则进行验证,updateUser
方法只对 UpdateGroup
组的验证规则进行验证。
嵌套验证
@Valid
:支持嵌套验证。如果一个对象包含另一个对象,在外部对象的字段上使用@Valid
注解,会对内部对象也进行验证。
java
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
class Address {
@NotNull
private String city;
// getter 和 setter 方法
}
class User {
@Valid
private Address address;
// getter 和 setter 方法
}
@Validated
:在嵌套验证上和@Valid
功能类似,不过在嵌套验证时通常还是搭配@Valid
使用。例如在方法参数是一个嵌套对象时,在外部对象上使用@Validated
,在内部对象字段上使用@Valid
进行嵌套验证。
注解位置与功能差异
@Valid
:通常用于对方法参数、方法返回值、构造函数参数等进行验证,主要关注的是对象本身的验证。@Validated
:除了具备@Valid
的功能外,还可以用在类级别,结合 Spring AOP 对整个类的方法进行验证。它更侧重于和 Spring 框架的集成,在 Spring 的环境中提供更强大的验证支持。