【问题标题】:How to convert HTML date to ZonedDateTime in SpringBoot/MVC/Web?如何在 Spring Boot/MVC/Web 中将 HTML 日期转换为 ZonedDateTime?
【发布时间】:2021-04-03 16:08:29
【问题描述】:

我正在使用 Spring Boot 编写代码,它是一个 Web 项目。我也在使用 thymeleaf 和 bootstrap。

我有一个模型,其中包含一个名为“validade”的 ZonedDateTime 变量。 在我的 HTML/Thymeleaf 文件中,我有一个日期选择器,可让您选择日、月和年。

但是,当我单击提交时,我收到了 spring boot 错误。如何告诉 spring boot 将此日期转换为 ZonedDateTime?我无法将此变量更改为 LocalDate 或 LocalDateTime。

出现意外错误(类型=错误请求,状态=400)。 object='tool' 的验证失败。错误计数:1 org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 1 个错误 字段“validade”上的对象“工具”中的字段错误:拒绝值 [2021-01-08];代码 [typeMismatch.tool.validade,typeMismatch.validade,typeMismatch.java.time.ZonedDateTime,typeMismatch]; 论据 [org.springframework.context.support.DefaultMessageSourceResolvable: 代码 [tool.validade,validade];论据 [];默认消息 [有效]];默认消息[无法转换类型的属性值 'java.lang.String' 到所需的类型 'java.time.ZonedDateTime' 属性“有效”;嵌套异常是 org.springframework.core.convert.ConversionFailedException: 失败 从类型 [java.lang.String] 转换为类型 [@org.springframework.format.annotation.DateTimeFormat @javax.persistence.Column java.time.ZonedDateTime] 的价值 '2021-01-08';嵌套异常是 java.lang.IllegalArgumentException: 值 [2021-01-08]] 的解析尝试失败


<form method="POST" th:object="${tool}"  th:action="@{/tools/add}">
...
    <div lang="pt-br" class='date'>
                           
    <input th:value="${tool.validade}" th:field="${tool.validade}" lang="pt-br" id='data-validade' type='date' data-date-format="YYYY/MM/DD" class="form-control" />
    
    </div>
...
</form>

public class Tool{
...
    @DateTimeFormat(pattern = "dd-MM-yyyy")
    @Column(nullable = true, unique = false)
    private ZonedDateTime validade;

}

【问题讨论】:

  • 如果发送“2021-01-08Z”或“08-01-2021Z”会发生什么?
  • 我不知道该怎么做
  • 在 JSP 中更改 type='string' ?或显示标准输入的值

标签: java spring spring-boot spring-mvc


【解决方案1】:

解决方案是实现我自己的转换器并通知 spring boot。 下面的代码解决了这个问题。

    import java.time.LocalDate;
    import java.time.ZoneId;
    import java.time.ZonedDateTime;
    import java.time.format.DateTimeFormatter;
    import org.springframework.boot.context.properties.ConfigurationPropertiesBinding;
    import org.springframework.core.convert.converter.Converter;
    import org.springframework.stereotype.Component;
    
    
@Component
@ConfigurationPropertiesBinding
public class ZonedDateTimeConverter implements Converter<String, ZonedDateTime> {

    @Override
    public ZonedDateTime convert(String source) {
        try {
            if (source == null) {
                return null;
            }
            
            if (source.contains(":") == false) {

                LocalDate ld = LocalDate.parse(source, DateTimeFormatter.ofPattern("yyyy-MM-dd"));

                ZonedDateTime atStartOfDay = ld.atStartOfDay(ZoneId.systemDefault());

                return atStartOfDay;
            } else {
                return ZonedDateTime.parse(source);
            }

        } catch (Exception ex) {
            //ex.printStackTrace();
        }

        return null;
    }

}

【讨论】:

    【解决方案2】:

    模式不正确,根据您的日志,发送了值 2021-01-08。这意味着日期遵循“yyyy-MM-dd”模式。

    【讨论】:

    • 仍然是一个错误:org.springframework.validation.BindException:org.springframework.validation.BeanPropertyBindingResult:1 个错误字段“validade”上的对象“工具”中的字段错误:拒绝值 [2021-01- 02];代码 [typeMismatch.tool.validade,typeMismatch.validade,typeMismatch.java.time.ZonedDateTime,typeMismatch];参数 [org.springframework.context.support.DefaultMessageSourceResolvable:代码 [tool.validade,validade];论据 [];默认消息[有效]];默认消息[无法转换...的属性值
    • 请问您为什么需要 ZonedDateTime?您只是发送没有时区的日期,为什么不使用 LocalDate ?
    猜你喜欢
    • 1970-01-01
    • 2022-07-07
    • 2018-04-04
    • 2019-12-16
    • 1970-01-01
    • 1970-01-01
    • 2018-02-24
    • 2019-05-11
    • 2019-08-05
    相关资源
    最近更新 更多