首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >正确解析的LocalDate会导致BindingResult错误。为什么?

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

Stack Overflow用户
提问于 2022-06-06 11:27:20
回答 1查看 759关注 0票数 0

我很困惑。我有一个域类Period,它有两个LocalDate属性startend,外加一个相应的控制器方法和模板来创建新的句点。

问题是:尽管请求模型显然正确地反序列化为具有两个正确的Period属性的LocalDate实例,但我仍然在BindingResult中出现错误,在BindingResult中,这些属性显然没有转换为LocalDate,而是保留为String的属性。验证失败的有:

代码语言:javascript
代码运行次数:0
运行
复制
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]

这是域类:

代码语言:javascript
代码运行次数:0
运行
复制
    @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?,
    )

这是用于创建新时期的控制器方法:

代码语言:javascript
代码运行次数:0
运行
复制
    @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"
            }
    
        }

这是Thymeleaf模板:

代码语言:javascript
代码运行次数:0
运行
复制
<!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()){设置断点时,调试器就是这样告诉我的。显然,period是一个具有两个LocalDate属性的Period实例,每个属性具有一个年份、一个月和一个日数(由-->指示)。在BindingResult内部也是如此。百事大吉!

但是,有两个错误拒绝用于创建日期的字符串值(由==>指示)。

代码语言:javascript
代码运行次数:0
运行
复制
    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模式,要么缺少胸腺嘧啶-extras Most 8时间。

我用的是弹簧靴2.6.7和胸腺3.0.15。我已经在依赖项中添加了thymeleaf extras java8时间。

EN

回答 1

Stack Overflow用户

发布于 2022-06-06 11:54:09

要解决这个问题,我必须做的唯一一件事就是使用:

代码语言:javascript
代码运行次数:0
运行
复制
@field:DateTimeFormat(pattern = "yyyy-MM-dd")

而不是:

代码语言:javascript
代码运行次数:0
运行
复制
@DateTimeFormat(pattern = "yyyy-MM-dd")

在我的域类中。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72516990

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档