代码之家  ›  专栏  ›  技术社区  ›  Michal Foksa

日期作为yaml属性文件中的映射键

  •  1
  • Michal Foksa  · 技术社区  · 8 年前

    如何用Spring引导将日期值绑定到YAML属性的JavaMap密钥?

    yaml属性文件:

    settings:
      calendar:
        2018-06-04: 2018-06-25
        2018-07-15: 2018-07-20
    

    属性类:

    目的 calendar 地图是从一个日期转换到另一个日期。

    @ConfigurationProperties(prefix = "settings")
    public class CalendarSettings {
    
      @DateTimeFormat(pattern = "yyyy-MM-dd")
      private Map<LocalDate, LocalDate> calendar = new HashMap<>();
    
      public Map<LocalDate, LocalDate> getCalendar() {
        return calendar;
      }
    
      public void setCalendar(
        Map<LocalDate, LocalDate> calendar) {
        this.calendar = calendar;
      }
    }
    

    使用此设置,我收到以下异常:

    Property: settings.null
    Value: 2018-06-04
    Reason: Failed to convert property value of type 'java.lang.String' to required type 'java.time.LocalDate' for property 'null'; 
    nested exception is java.lang.IllegalStateException: Cannot convert value of type 'java.lang.String' to required type 'java.time.LocalDate': 
    no matching editors or conversion strategy found
    

    我正在努力研究如何在 CalendarSettings.class 如果可能的话。或者如何创建某种反序列化程序。

    1 回复  |  直到 8 年前
        1
  •  4
  •   Dimitri Mestdagh Lancer.Yan    8 年前

    如果以调试模式运行应用程序,则可能会引发以下异常:

    Caused by: java.time.format.DateTimeParseException: Text '2018-06-04' could not be parsed at index 4
        at java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:1949) ~[na:1.8.0_162]
        at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1851) ~[na:1.8.0_162]
        at java.time.LocalDate.parse(LocalDate.java:400) ~[na:1.8.0_162]
        at org.springframework.format.datetime.standard.TemporalAccessorParser.parse(TemporalAccessorParser.java:69) ~[spring-context-5.0.6.RELEASE.jar:5.0.6.RELEASE]
        at org.springframework.format.datetime.standard.TemporalAccessorParser.parse(TemporalAccessorParser.java:46) ~[spring-context-5.0.6.RELEASE.jar:5.0.6.RELEASE]
        at org.springframework.format.support.FormattingConversionService$ParserConverter.convert(FormattingConversionService.java:200) ~[spring-context-5.0.6.RELEASE.jar:5.0.6.RELEASE]
    

    失败的原因是默认的解析器( TemporalAccessorParser )使用本地化日期转换器映射 String 到A LocalDate . 要解决此问题,可以编写自己的转换器:

    @Component
    @ConfigurationPropertiesBinding
    public class LocalDateConverter implements Converter<String, LocalDate> {
    
        @Override
        public LocalDate convert(String timestamp) {
            return LocalDate.parse(timestamp);
        }
    }
    

    如果您将此组件注册到 @ConfigurationPropertiesBinding 注释,它将在分析应用程序属性时被提取。这个 LocalDate.parse(CharSequence) 方法使用 ISO_LOCAL_DATE 转换器,在你的情况下应该可以正常工作。