当前位置: 首页 > 知识库问答 >
问题:

正确解析的LocalDate会导致BindingResult错误。为什么?

马亮
2023-03-14

我很困惑。我有一个域类 Period,其中包含两个 LocalDate 属性 beginend,以及一个用于创建新周期的相应控制器方法和模板。

问题:即使请求模型显然被正确地反序列化为具有两个正确的LocalDate属性的周期实例,我仍然在BiningResult中遇到错误,其中属性显然没有转换为LocalDate,而是保留为Strings。验证失败,出现以下情况:

end: Failed to convert property value of type 'java.lang.String' to required type 'java.time.LocalDate' for property 'end'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [java.time.LocalDate] for value '2022-06-02'; nested exception is java.lang.IllegalArgumentException: Parse attempt failed for value [2022-06-02]
start: Failed to convert property value of type 'java.lang.String' to required type 'java.time.LocalDate' for property 'start'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [java.time.LocalDate] for value '2022-06-01'; nested exception is java.lang.IllegalArgumentException: Parse attempt failed for value [2022-06-01]

这是域类:

    @Entity
    @Table(name = "period")
    class Period(
    
        @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
        val id: Long = 0,
    
        @DateTimeFormat(pattern = "yyyy-MM-dd")
        var start: LocalDate?,
    
        @DateTimeFormat(pattern = "yyyy-MM-dd")
        var end: LocalDate?,
    )

这是创建新周期的控制器方法:

    @PostMapping("/period/add")
        fun updatePeriod(@ModelAttribute("period") @Validated period: Period, result: BindingResult, model: Model) : String {
            if(result.hasErrors()){
                result
                    .getFieldErrors()
                    .stream()
                    .forEach{f -> println(f.getField() + ": " + f.getDefaultMessage())};
                return "add-period"
            }
            else {
                periodRepository.save(period)
                return "redirect:/period"
            }
    
        }

这是百里香叶模板:

<!DOCTYPE html>
<html>
<head lang="en">
    <title th:text="${title}"></title>
    <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>
</head>
<body>
<h1 th:text="'New Period'"></h1>
<form action="#" th:action="@{/period/add}" th:object="${period}" method="post">
<table>
    <tr>
        <td>Start Date</td>
        <td><input id="start" type="date"  name="start"
                   min="2000-01-01" max="2023-12-31"
                   th:value="*{start}"
                   th:field="*{start}"/></td>
    </tr>
    <tr>
        <td>End Date</td>
        <td><input id="end" type="date"  name="end"
                   min="2000-01-01" max="2023-12-31"
                   th:value="*{end}"
                   th:field="*{end}"/></td>
    </tr>

</table>
<input type="submit" value="Submit" />
</form>

这是调试器在控制器中的if(result.hasErrors ()){处设置断点时告诉我的。显然,时期是一个时期实例,具有两个LocalDate属性,每个属性都有一年、月和日(由指示-

但是,有两个错误会拒绝用于创建日期的 String 值(由 == 指示)

    this = {WebController@13784} nl.tracking.core.web.WebController@a4388f1
    period = {Period@13787} nl.tracking.core.domain.Period@111cd8c3
     id = 0
-->  start = {LocalDate@17522} "2022-06-01"
-->   year = 2022
-->   month = 6
-->   day = 1
     end = {LocalDate@17523} "2022-06-02"
    result = {BeanPropertyBindingResult@13788} "org.springframework.validation.BeanPropertyBindingResult: 2 errors\nField error in object 'period' on field 'end': rejected value [2022-06-02]; codes [typeMismatch.period.end,typeMismatch.end,typeMismatch.java.time.LocalDate,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [period.end,end]; arguments []; default message [end]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'java.time.LocalDate' for property 'end'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [java.time.LocalDate] for value '2022-06-02'; nested exception is java.lang.IllegalArgumentException: Parse attempt failed for value [2022-06-02]]\nField error in object 'period' on field 'start': rejected value [2022-06-01]; codes [typeMismatch.period.start,typeMismatch.start,typeMismatch.java.time.LocalDate,typeMismatch]; arguments [org.springfra"
-->  target = {Period@13787} nl.tracking.core.domain.Period@111cd8c3
     autoGrowNestedPaths = true
     autoGrowCollectionLimit = 256
     beanWrapper = {BeanWrapperImpl@17526} "org.springframework.beans.BeanWrapperImpl: wrapping object [nl.tracking.core.domain.Period@111cd8c3]"
     conversionService = {WebConversionService@17527} "ConversionService converters =\n\t@org.springframework.format.annotation.DateTimeFormat java.lang.Long -> java.lang.String: org.springframework.format.datetime.DateTimeFormatAnnotationFormatterFactory@4a422ef1,@org.springframework.format.annotation.NumberFormat java.lang.Long -> java.lang.String: org.springframework.format.number.NumberFormatAnnotationFormatterFactory@35e37f8f\n\t@org.springframework.format.annotation.DateTimeFormat java.time.LocalDate -> java.lang.String: org.springframework.format.datetime.standard.Jsr310DateTimeFormatAnnotationFormatterFactory@1f4c8763,java.time.LocalDate -> java.lang.String : org.springframework.format.datetime.standard.TemporalAccessorPrinter@61841139\n\t@org.springframework.format.annotation.DateTimeFormat java.time.LocalDateTime -> java.lang.String: org.springframework.format.datetime.standard.Jsr310DateTimeFormatAnnotationFormatterFactory@1f4c8763,java.time.LocalDateTime -> java.lang.String : org.springframework.format.datetime.standard.TemporalAcces"
     objectName = "period"
     messageCodesResolver = {DefaultMessageCodesResolver@17529} 
     errors = {ArrayList@17530}  size = 2
      0 = {FieldError@17550} "Field error in object 'period' on field 'end': rejected value [2022-06-02]; codes [typeMismatch.period.end,typeMismatch.end,typeMismatch.java.time.LocalDate,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [period.end,end]; arguments []; default message [end]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'java.time.LocalDate' for property 'end'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [java.time.LocalDate] for value '2022-06-02'; nested exception is java.lang.IllegalArgumentException: Parse attempt failed for value [2022-06-02]]"
       field = "end"
==>    rejectedValue = "2022-06-02"
       bindingFailure = true
       objectName = "period"
==>    source = {TypeMismatchException@17556} "org.springframework.beans.TypeMismatchException: Failed to convert property value of type 'java.lang.String' to required type 'java.time.LocalDate' for property 'end'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [java.time.LocalDate] for value '2022-06-02'; nested exception is java.lang.IllegalArgumentException: Parse attempt failed for value [2022-06-02]"
       codes = {String[4]@17557} ["typeMismatch.pe...", "typeMismatch.en...", "typeMismatch.ja...", "typeMismatch"]
       arguments = {Object[1]@17558} 
==>    defaultMessage = "Failed to convert property value of type 'java.lang.String' to required type 'java.time.LocalDate' for property 'end'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [java.time.LocalDate] for value '2022-06-02'; nested exception is java.lang.IllegalArgumentException: Parse attempt failed for value [2022-06-02]"
      1 = {FieldError@17551} "Field error in object 'period' on field 'start': rejected value [2022-06-01]; codes [typeMismatch.period.start,typeMismatch.start,typeMismatch.java.time.LocalDate,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [period.start,start]; arguments []; default message [start]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'java.time.LocalDate' for property 'start'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [java.time.LocalDate] for value '2022-06-01'; nested exception is java.lang.IllegalArgumentException: Parse attempt failed for value [2022-06-01]]"
     fieldTypes = {HashMap@17531}  size = 0
     fieldValues = {HashMap@17532}  size = 0
     suppressedFields = {HashSet@17533}  size = 0
     nestedPath = ""
     nestedPathStack = {ArrayDeque@17535}  size = 0
--> model = {BindingAwareModelMap@13789}  size = 2
     "period" -> {Period@13787} nl.tracking.core.domain.Period@111cd8c3
      key = "period"
      value = {Period@13787} nl.tracking.core.domain.Period@111cd8c3
       id = 0
-->    start = {LocalDate@17522} "2022-06-01"
-->     year = 2022
-->     month = 6
-->     day = 1
       end = {LocalDate@17523} "2022-06-02"
     "org.springframework.validation.BindingResult.period" -> {BeanPropertyBindingResult@13788} "org.springframework.validation.BeanPropertyBindingResult: 2 errors\nField error in object 'period' on field 'end': rejected value [2022-06-02]; codes [typeMismatch.period.end,typeMismatch.end,typeMismatch.java.time.LocalDate,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [period.end,end]; arguments []; default message [end]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'java.time.LocalDate' for property 'end'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [java.time.LocalDate] for value '2022-06-02'; nested exception is java.lang.IllegalArgumentException: Parse attempt failed for value [2022-06-02]]\nField error in object 'period' on field 'start': rejected value [2022-06-01]; codes [typeMismatch.period.start,typeMismatch.start,typeMismatch.java.time.LocalDate,typeMismatch]; arguments [org.springfra"

这对我来说毫无意义...我四处搜索了S/O,但找不到解决方案。大多数人要么使用不匹配的@DateTimeFormat模式,要么缺少thymeleaf-transas-java8time。

我使用的是spring-boot2.6.7和thymeleaf 3.0.15。我已经将thymeleaf-transas-java8time添加到依赖项中。


共有1个答案

袁泓
2023-03-14

我唯一要做的就是使用:

kotlin prettyprint-override">@field:DateTimeFormat(pattern = "yyyy-MM-dd")

而不是:

@DateTimeFormat(pattern = "yyyy-MM-dd")

在我的领域课上。

 类似资料:
  • 问题内容: 遇到一个错误地使用 而不是 在其代码中的人,它没有显示为编译错误。 是因为 是相同的 ? 问题答案: 没有编译错误,因为它是有效的(尽管相当无用) 一元运算符 ,其使用方式与以下方式相同: Java语言规范中的相关部分是Unary Plus运算符+(第15.15.3节) 。它指定调用一元运算会导致操作数的一元数值提升(第5.6.1节)。这意味着: * 如果操作数是编译时类型的,,,或,

  • 我使用以下源代码创建了自己的SDF模式:https://docs.oracle.com/en/java/javase/13/docs/api/java.base/java/text/simpledateformat.html 导致以下错误,我不明白原因: 任何帮助都会很棒! 编辑:我正在使用JDK 13 进程结束,退出代码为%1

  • 根据SQL字符串组合文档,我想在postgresql数据库中执行DELETE语句: 这将导致以下错误: 另一方面,类似的execute工作正常: 我真的看不出有什么区别...

  • 给定: 和输出: ...要打印秒的图案是什么?这个问题很蠢,但让我有点发疯 我需要:

  • 我需要解析一个日期,当我解析一个无效的日期“2007年2月29日”时,它将以dd/MM/yyyy的格式返回给我,作为本地日期2007-02-28,代码如下: 但是,如果我使用ISO格式(没有DateTimeFormatter)进行解析,则会出现异常,代码如下: 例外情况: 所以我的问题是,我想考虑一下: 由于无效,我如何使用LocalDate呢。作语法分析

  • 我有XML数据在数据库(不是文件),我需要解析它,以提供可能写测试来验证数据在XML xml(内容数据): [致命错误]:14:2:根元素后面的文档中的标记必须格式良好。org.xml.sax.SaxParseException;亚麻编号:14;专栏编号:2;根元素后面的文档中的标记必须格式良好。位于com.sun.org.apache.xerces.internal.parsers.dompar