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

Spring Boot中验证请求头日期格式的正确方法(注解无效问题)

问题描述

我有如下Spring控制器代码:

@RestController
@RequestMapping("/initiatiation-task/v1")
public class LoginInitiationTaskController {

    private final LoginInitiationTaskService loginInitiationTaskService;

    @PostMapping("/login")
    public ResponseEntity<InitiateLoginResponse> initiateLogin(
            @Valid @RequestHeader("Date")  @DateTimeFormat(pattern = "EEE, dd MMM yyyy HH:mm:ss Z") ZonedDateTime date) {

        // ...
    }

}

我需要验证请求头中的日期格式,但上述配置无法生效。我还尝试了用@JsonFormat注解:

@JsonFormat( pattern = "EEE, dd MMM yyyy HH:mm:ss Z", timezone="GMT") ZonedDateTime date

当发送带有格式为Sun, 01 Jan 2023 06:49:53 GMT的请求头时,Spring抛出异常:

org.springframework.web.method.annotation.MethodArgumentTypeMismatchException:
Failed to convert value of type 'java.lang.String' to required type
'java.time.ZonedDateTime'; Failed to convert from type
[java.lang.String] to type
[@org.springframework.web.bind.annotation.RequestHeader
@com.fasterxml.jackson.annotation.JsonFormat java.time.ZonedDateTime]
for value 'Sun, 01 Jan 2023 06:49:53 GMT'

请问如何正确验证请求头中的日期格式?


解决方法

方法一:自定义转换器(推荐)

Spring处理请求头参数时不认可@JsonFormat,而@DateTimeFormat对ZonedDateTime的支持需要配合自定义转换器。可以创建一个转换器专门处理RFC1123格式的日期转换:

  1. 编写自定义转换器类:
import org.springframework.core.convert.converter.Converter;
import org.springframework.stereotype.Component;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;

@Component
public class Rfc1123ZonedDateTimeConverter implements Converter<String, ZonedDateTime> {

    private static final DateTimeFormatter RFC_1123_FORMATTER = DateTimeFormatter.RFC_1123_DATE_TIME;

    @Override
    public ZonedDateTime convert(String source) {
        return ZonedDateTime.parse(source, RFC_1123_FORMATTER);
    }
}
  1. 控制器方法中直接使用@RequestHeader,无需额外格式化注解:
@PostMapping("/login")
public ResponseEntity<InitiateLoginResponse> initiateLogin(
        @Valid @RequestHeader("Date") ZonedDateTime date) {
    // ...
}

格式不匹配时会自动抛出DateTimeParseException,可以通过全局异常处理器统一返回错误响应。

方法二:@DateTimeFormat指定英文Locale

@DateTimeFormat默认用系统Locale,而RFC1123格式的英文星期、月份缩写需要指定英文Locale才能解析:

@PostMapping("/login")
public ResponseEntity<InitiateLoginResponse> initiateLogin(
        @Valid @RequestHeader("Date")
        @DateTimeFormat(pattern = "EEE, dd MMM yyyy HH:mm:ss Z", locale = "en_US") 
        ZonedDateTime date) {
    // ...
}

注意:Spring Boot 2.x及以上默认已支持Java 8时间API,无需额外配置。

方法三:手动解析+自定义验证

如果需要更灵活的错误处理,可以先接收字符串类型的请求头,手动解析验证:

import javax.validation.constraints.NotBlank;
import java.time.format.DateTimeParseException;

@PostMapping("/login")
public ResponseEntity<InitiateLoginResponse> initiateLogin(
        @NotBlank @RequestHeader("Date") String dateStr) {
    try {
        ZonedDateTime date = ZonedDateTime.parse(dateStr, DateTimeFormatter.RFC_1123_DATE_TIME);
        // 业务逻辑处理
    } catch (DateTimeParseException e) {
        // 返回格式错误的响应
        return ResponseEntity.badRequest().body(new InitiateLoginResponse("日期格式错误,请遵循RFC1123标准"));
    }
}

内容的提问来源于stack exchange,提问作者Farhan stands with Palestine

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 13:30:51