You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SpringBoot请求体校验:如何禁止传入空列表?

解决SpringBoot中列表非空且非空列表的校验问题

一、使用标准校验注解解决

你当前用的@NonNull是Lombok注解,它仅校验对象不为null,但空列表([])本身是一个存在的List对象,所以不会触发校验失败。要同时满足“属性必须存在、列表不为空列表”的要求,直接用JSR-380(或Jakarta Validation)的标准注解即可:

1. 选择合适的注解

  • @NotEmpty:同时校验对象不为null、集合/数组不为空(元素个数>0),完全匹配你的需求。
  • @Size(min = 1):仅校验集合元素个数至少为1,若要同时确保属性存在,需配合@NotNull(不过@NotEmpty已经包含了@NotNull的逻辑)。

2. 修改BodyDto代码

根据你的SpringBoot版本选择对应的注解包:

  • SpringBoot 2.x:使用javax.validation.constraints包下的注解
@Getter
@Setter
@AllArgsConstructor
public class BodyDto {

    @NotEmpty(message = "route不能为空且不能是空列表")
    private List<String> route;
}
  • SpringBoot 3.x:使用jakarta.validation.constraints包下的注解(SpringBoot 3+切换到Jakarta EE规范)
@Getter
@Setter
@AllArgsConstructor
public class BodyDto {

    @NotEmpty(message = "route不能为空且不能是空列表")
    private List<String> route;
}

3. 确保依赖正确

如果之前没引入校验依赖,需要添加SpringBoot的validation starter:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
</dependency>

二、注解不生效的排查点

如果添加注解后仍然没触发校验,检查以下几点:

  • 注解包是否导错:别误导入Lombok或Hibernate的同名注解,必须是javax.validation.constraints(SpringBoot2)或jakarta.validation.constraints(SpringBoot3)下的@NotEmpty。
  • 控制器方法是否正确标记:确保@RequestBody前的@Valid(或Spring的@Validated)注解存在,你当前的控制器代码是正确的,但如果用了@Validated需要注意分组规则。
  • 是否捕获校验异常:默认情况下,校验失败会抛出MethodArgumentNotValidException,如果没有全局异常处理器,可能看不到明确的错误响应。可以添加全局异常处理器返回友好提示:
@RestControllerAdvice
public class GlobalValidationExceptionHandler {

    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity<Map<String, String>> handleValidationErrors(MethodArgumentNotValidException ex) {
        Map<String, String> errorMap = new HashMap<>();
        ex.getBindingResult().getFieldErrors().forEach(error -> 
            errorMap.put(error.getField(), error.getDefaultMessage())
        );
        return new ResponseEntity<>(errorMap, HttpStatus.BAD_REQUEST);
    }
}

三、自定义校验(复杂场景可选)

如果需要更定制化的校验规则(比如同时校验列表元素不为空),可以自定义校验注解:

1. 定义自定义注解

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = NonEmptyListValidator.class)
public @interface NonEmptyList {
    String message() default "列表不能为空且不能是空列表";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}

2. 实现校验逻辑

public class NonEmptyListValidator implements ConstraintValidator<NonEmptyList, List<?>> {

    @Override
    public boolean isValid(List<?> list, ConstraintValidatorContext context) {
        // 校验列表不为null且元素个数>0
        return list != null && !list.isEmpty();
    }
}

3. 在Dto中使用

@Getter
@Setter
@AllArgsConstructor
public class BodyDto {

    @NonEmptyList
    private List<String> route;
}

内容的提问来源于stack exchange,提问作者Oğuz Öztınaz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 02:15:45