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

如何将Spring控制器中Java对象类型的请求参数设为必填?

嘿,这个场景太常见了!Spring默认确实会把封装对象的参数都当成可选的,但要设置必填项其实很简单,用JSR-380的校验注解就能轻松搞定,我给你一步步拆解:

1. 先引入校验依赖

如果是Spring Boot项目,直接加这个starter就行:

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

要是普通Spring项目,需要引入hibernate-validator和相关API依赖。

2. 给Filter类的字段加校验注解

根据字段类型选对应的注解:

  • 对于Integer这种包装类,用@NotNull(确保参数不为null,不会接受空字符串转成null的情况)
  • 对于String类型,要是需要非空且不能是空白字符串,用@NotBlank;如果允许空字符串但不能为null,用@NotEmpty

修改后的Filter类示例:

import javax.validation.constraints.NotNull;
import javax.validation.constraints.NotBlank;

public class Filter {
    @NotNull(message = "page参数不能为空,请传入有效页码")
    private Integer page;

    @NotNull(message = "size参数不能为空,请传入每页条数")
    private Integer size;

    @NotBlank(message = "sort参数不能为空,请指定排序字段")
    private String sort;

    // 其他众多参数...
    // 别忘了加getter和setter,Spring需要通过它们注入参数
}

3. 在控制器参数上触发校验

只需要在Filter参数前面加上@Validated(或者@Valid)注解,Spring就会自动帮你校验参数:

@GetMapping("/users")
public ResponseEntity<UserDto> getUsers(@Validated Filter filter) {
    return ResponseEntity.ok(userService.findUsers(filter));
}

这里说下@Valid和@Validated的小区别:@Valid是JSR标准注解,@Validated是Spring的扩展,支持分组校验、校验组序列这些高级功能,一般用@Validated更灵活。

4. 处理校验失败的情况

如果参数不符合要求,Spring会抛出MethodArgumentNotValidException,你可以写个全局异常处理器来捕获它,返回友好的错误信息给前端:

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
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 GlobalValidationExceptionHandler {

    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity<Map<String, String>> handleValidationErrors(MethodArgumentNotValidException ex) {
        Map<String, String> errorMap = new HashMap<>();
        // 遍历所有校验错误,把字段名和错误信息对应起来
        ex.getBindingResult().getAllErrors().forEach(error -> {
            String fieldName = ((FieldError) error).getField();
            String errorMessage = error.getDefaultMessage();
            errorMap.put(fieldName, errorMessage);
        });
        return new ResponseEntity<>(errorMap, HttpStatus.BAD_REQUEST);
    }
}

进阶:分组校验(部分场景必填,部分可选)

要是你有不同的接口场景,比如有的接口需要page和size必填,有的不需要,就可以用分组校验:

  1. 先定义两个分组接口:
public interface RequiredPagingGroup {}
public interface OptionalPagingGroup {}
  1. 在Filter的注解上指定分组:
@NotNull(message = "page参数不能为空", groups = RequiredPagingGroup.class)
private Integer page;
  1. 控制器里指定要触发的分组:
@GetMapping("/users")
public ResponseEntity<UserDto> getUsers(@Validated(RequiredPagingGroup.class) Filter filter) {
    return ResponseEntity.ok(userService.findUsers(filter));
}

这样就能灵活控制不同场景下的必填参数啦!

内容的提问来源于stack exchange,提问作者Archie

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:45:35