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

Spring中处理可为Null的日期格式化及Thymeleaf表单参数问题

问题解决思路与方案

一、修复Null值报错

你遇到的错误本质是:前端提交了空的日期参数(比如空字符串),Spring尝试将其转换为java.util.Date时得到null,但@RequestParam默认required=true,即使参数存在但转换结果为null,依然会触发“必填参数缺失”的错误。

直接的解决方法是在@RequestParam中显式关闭必填校验,并允许参数为null:

@PostMapping("/submit-form")
public String processForm(
    // 关闭必填校验,允许参数为null
    @RequestParam(name = "date_smth_form", required = false)
    // 指定你需要的日期格式
    @DateTimeFormat(pattern = "yyyy.MM.dd") 
    Date dateSmth,
    // 其他表单参数...
) {
    // 业务逻辑处理
    return "result-page";
}

如果需要给空参数设置默认值(比如当前日期),可以加上defaultValue属性:

@RequestParam(name = "date_smth_form", required = false, defaultValue = "#{T(java.time.LocalDate).now().format(T(java.time.format.DateTimeFormatter).ofPattern('yyyy.MM.dd'))}")
@DateTimeFormat(pattern = "yyyy.MM.dd") 
Date dateSmth

二、确保日期始终为yyyy.MM.dd格式

1. 控制器参数解析适配

把原来的@DateTimeFormat(iso=DateTimeFormat.ISO.DATE)改成指定pattern="yyyy.MM.dd",这样Spring会严格按照你需要的格式解析前端传入的日期字符串,避免ISO标准格式(yyyy-MM-dd)的干扰。

2. 实体类字段格式化

java.util.Date本身包含时间戳,要确保只保留日期部分,需要在实体类字段上添加格式化注解,并截断时间部分:

// 实体类字段
@DateTimeFormat(pattern = "yyyy.MM.dd")
private Date dateSmth;

// Getter方法中截断时间,只保留日期
public Date getDateSmth() {
    if (dateSmth == null) return null;
    Calendar cal = Calendar.getInstance();
    cal.setTime(dateSmth);
    cal.set(Calendar.HOUR_OF_DAY, 0);
    cal.set(Calendar.MINUTE, 0);
    cal.set(Calendar.SECOND, 0);
    cal.set(Calendar.MILLISECOND, 0);
    return cal.getTime();
}

// Setter方法保持格式化规则
@DateTimeFormat(pattern = "yyyy.MM.dd")
public void setDateSmth(Date dateSmth) {
    this.dateSmth = dateSmth;
}

3. Thymeleaf前端回显适配

HTML5的type="date"输入框默认只接受yyyy-MM-dd格式的字符串,回显时需要把实体类的Date对象格式化为该格式,确保前端能正确显示:

<input type="date" 
       th:field="*{dateSmth}" 
       th:value="${#dates.format(dateSmth, 'yyyy-MM-dd')}" />

提交时前端会自动把日期转为yyyy-MM-dd字符串,后端通过@DateTimeFormat(pattern="yyyy.MM.dd")解析成Date对象,两者格式不冲突,Spring的日期解析器会正确处理转换逻辑。

三、可选:全局日期格式化配置

如果项目中有大量日期参数需要统一格式,可以配置全局规则,避免每个参数都加注解:

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
    @Override
    public void addFormatters(FormatterRegistry registry) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy.MM.dd");
        
        registry.addFormatter(new DateFormatter() {
            @Override
            public Date parse(String text, Locale locale) throws ParseException {
                if (text == null || text.trim().isEmpty()) {
                    return null;
                }
                LocalDate localDate = LocalDate.parse(text, formatter);
                return Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant());
            }

            @Override
            public String print(Date date, Locale locale) {
                if (date == null) {
                    return "";
                }
                LocalDate localDate = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
                return formatter.format(localDate);
            }
        });
    }
}

配置后,控制器中的@RequestParam Date参数会自动按照yyyy.MM.dd格式解析,无需再添加@DateTimeFormat注解。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 11:37:10