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

Spring Boot中如何验证@RequestHeader?请求头缺失与格式错误校验

Hey there! Let's break down your Spring Boot request header validation questions step by step.

问题1:如何在Spring Boot中验证@RequestHeader?

在Spring Boot里验证请求头,主要有几种常用方式,你可以根据需求复杂度来选择:

1. 基础必填验证

如果只是要确保请求头必须存在,直接用@RequestHeader的required属性就能搞定:

public ResponseEntity<> update(@RequestHeader(value="last-modified-date", required = true) String lastModDate, ...)

如果请求头缺失,Spring会自动返回400 Bad Request。

2. 结合JSR-380注解做简单格式校验

如果需要验证格式(比如正则匹配),可以用Spring支持的JSR-380注解(比如@Pattern、@NotBlank),前提是你已经引入了spring-boot-starter-validation依赖:

public ResponseEntity<> update(
    @RequestHeader(value="last-modified-date") 
    @Pattern(regexp = "^[A-Za-z]{3}, \\d{2} [A-Za-z]{3} \\d{4} \\d{2}:\\d{2}:\\d{2} GMT$", 
             message = "日期格式必须为 'Mon, 28 Aug 2017 02:51:09 GMT'")
    String lastModDate, ...)

这种方式适合简单的格式校验,但如果是日期解析这类需要业务逻辑判断的验证,自定义校验会更靠谱。

3. 自定义校验器(复杂场景)

对于像日期解析这类需要逻辑判断的验证,最好自定义一个校验注解和对应的校验器,代码更清晰灵活——这也是解决问题2的核心思路。


问题2:实现last-modified-date的自定义校验(缺失+格式验证)

针对你提供的PUT接口,我们需要实现两个校验逻辑:① 请求头不能缺失;② 格式必须符合Mon, 28 Aug 2017 02:51:09 GMT。下面是具体实现步骤:

步骤1:创建自定义校验注解

先定义一个@ValidLastModifiedDate注解,用来标记需要校验的请求头参数:

import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.*;

@Documented
@Constraint(validatedBy = LastModifiedDateValidator.class)
@Target({ElementType.PARAMETER, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface ValidLastModifiedDate {
    String message() default "请求头last-modified-date格式错误,必须为 'Mon, 28 Aug 2017 02:51:09 GMT' 格式,或请求头缺失";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}

步骤2:实现校验器逻辑

接下来写对应的校验器LastModifiedDateValidator,负责实际的日期解析和校验:

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;

public class LastModifiedDateValidator implements ConstraintValidator<ValidLastModifiedDate, String> {
    // 用Java 8+的内置格式,刚好匹配需求的GMT日期格式
    private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.RFC_1123_DATE_TIME;

    @Override
    public boolean isValid(String lastModDate, ConstraintValidatorContext context) {
        // 先判断参数是否为空(处理请求头缺失的情况)
        if (lastModDate == null || lastModDate.isBlank()) {
            return false;
        }
        // 尝试解析日期,失败则返回false
        try {
            ZonedDateTime.parse(lastModDate, DATE_FORMATTER);
            return true;
        } catch (DateTimeParseException e) {
            return false;
        }
    }
}

这里用ZonedDateTime和DateTimeFormatter比旧的SimpleDateFormat更安全,也更贴合现代Java开发习惯。

步骤3:在接口中使用自定义注解

修改你的PUT接口,给lastModDate参数加上@ValidLastModifiedDate注解,同时记得在类或者方法上加上@Validated注解——这是Spring触发校验的关键:

import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

@RestController
@Validated // 必须加这个注解,否则自定义校验不会生效
public class ExampleController {

    @RequestMapping(value = "/example/{id}", method = RequestMethod.PUT)
    public ResponseEntity<?> update(
            @RequestHeader(value="last-modified-date") 
            @ValidLastModifiedDate String lastModDate, 
            HttpServletRequest request, 
            @RequestBody ReBody rebody, 
            @PathVariable("id") int id) throws Exception {
        // 业务逻辑
        return ResponseEntity.ok("更新成功");
    }
}

步骤4:处理校验异常(可选)

默认情况下,校验失败会返回500 Internal Server Error,你可以自定义全局异常处理器,返回更友好的400 Bad Request和错误信息:

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.HashMap;
import java.util.Map;

@RestControllerAdvice
public class GlobalExceptionHandler {

    // 处理@Validated触发的校验异常
    @ExceptionHandler(ConstraintViolationException.class)
    public ResponseEntity<Map<String, String>> handleConstraintViolationException(ConstraintViolationException ex) {
        Map<String, String> errors = new HashMap<>();
        for (ConstraintViolation<?> violation : ex.getConstraintViolations()) {
            errors.put("message", violation.getMessage());
        }
        return new ResponseEntity<>(errors, HttpStatus.BAD_REQUEST);
    }
}

这样当请求头缺失或者格式错误时,会返回类似下面的响应:

{
    "message": "请求头last-modified-date格式错误,必须为 'Mon, 28 Aug 2017 02:51:09 GMT' 格式,或请求头缺失"
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:04:50