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

Spring Boot中在DTO层验证请求参数的ISO-8601格式日期

如何在DTO层验证Date字段为ISO-8601格式

当然可以在DTO层对endDate字段做ISO-8601格式的验证!下面分享两种实用的实现方式,你可以根据自己的场景选择:

方法1:自定义验证注解(推荐)

这种方式最灵活,能直接对Date类型字段做格式校验,而且和现有的@NotNull注解完美配合,步骤很清晰:

1.1 先定义自定义验证注解

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

@Documented
@Constraint(validatedBy = Iso8601DateValidator.class)
@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface Iso8601Date {
    String message() default "日期格式必须为ISO-8601标准格式(例如:2007-04-05T14:30Z)";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}

1.2 实现注解对应的验证逻辑

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class Iso8601DateValidator implements ConstraintValidator<Iso8601Date, Date> {
    // 严格匹配ISO-8601的指定格式
    private static final String ISO_8601_PATTERN = "yyyy-MM-dd'T'HH:mm'Z'";

    @Override
    public boolean isValid(Date date, ConstraintValidatorContext context) {
        // null的情况交给@NotNull处理,这里只验证非null的日期格式
        if (date == null) {
            return true;
        }
        try {
            SimpleDateFormat sdf = new SimpleDateFormat(ISO_8601_PATTERN);
            sdf.setLenient(false); // 关闭宽松解析,确保格式完全匹配
            // 把Date转成字符串再转回来,对比是否一致
            String formattedDate = sdf.format(date);
            Date parsedDate = sdf.parse(formattedDate);
            return date.equals(parsedDate);
        } catch (ParseException e) {
            return false;
        }
    }
}

1.3 在DTO字段上加上这个注解

import com.fasterxml.jackson.annotation.JsonProperty;
import javax.validation.constraints.NotNull;

public class ReceivedDTO {
    @JsonProperty("end_date")
    @NotNull(message = "end_date不能为空")
    @Iso8601Date // 加上自定义格式验证注解
    private Date endDate;

    // getter、setter省略
}

方法2:转成String字段用@Pattern验证

如果你能接受调整DTO的字段类型,把Date改成String,可以直接用JSR-380自带的@Pattern注解做正则校验,之后再在服务层转成Date类型:

import com.fasterxml.jackson.annotation.JsonProperty;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class ReceivedDTO {
    @JsonProperty("end_date")
    @NotNull(message = "end_date不能为空")
    // 正则匹配ISO-8601的指定格式
    @Pattern(regexp = "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}Z$", 
             message = "日期格式必须为ISO-8601标准格式(例如:2007-04-05T14:30Z)")
    private String endDate;

    // 可以加个方法把字符串转成Date,方便后续使用
    public Date getEndDateAsDate() throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm'Z'");
        sdf.setLenient(false);
        return sdf.parse(endDate);
    }

    // getter、setter省略
}

额外小建议

如果你用的是Java 8及以上,真心推荐用OffsetDateTime(或者LocalDateTime)替代Date,这些新的日期API天生支持ISO-8601格式,配合Jackson的@JsonFormat注解,既能自动解析/序列化,又能间接实现格式校验:

import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonProperty;
import javax.validation.constraints.NotNull;
import java.time.OffsetDateTime;

public class ReceivedDTO {
    @JsonProperty("end_date")
    @NotNull(message = "end_date不能为空")
    @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm'Z'")
    private OffsetDateTime endDate;

    // getter、setter省略
}

这种情况下,如果前端传的格式不对,Spring的消息转换器会直接抛出HttpMessageNotReadableException,你可以通过全局异常处理器捕获这个异常,返回友好的错误提示给前端。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 03:56:49