【问题标题】:Spring: create LocalDate or LocalDateTime from @Value parameterSpring:从 @Value 参数创建 LocalDate 或 LocalDateTime
【发布时间】:2018-02-02 03:48:29
【问题描述】:

在 spring 项目中,我想从 @Autowired 构造函数参数创建一个 LocalDate,其值在 .properties 文件中。我想做两件事:

1.如果属性文件中包含属性my.date,则需要通过解析属性值来创建参数

设置属性时,以及当我使用以下内容时:

@DateTimeFormat(pattern = "yyyy-MM-dd") @Value("${my.date}") LocalDate myDate,
...

我收到此错误: java.lang.IllegalStateException:无法将类型“java.lang.String”的值转换为所需类型“java.time.LocalDate”:找不到匹配的编辑器或转换策略

我还使用了iso = ... 来使用具有相同结果的 ISO 日期。

2.如果属性不在属性文件中,则应使用LocalDate.now()创建参数

我尝试使用这样的默认值:

@Value("${my.date:#{T(java.time.LocalDate).now()}}") LocalDate myDate,
...

但我得到了同样的错误。

请原谅我对 Spring 的无知,但是我该如何实现这两个目标呢?

【问题讨论】:

    标签: java spring spring-boot autowired


    【解决方案1】:

    我知道两种方法。一个对任何对象都是通用的 - 在自定义设置器上使用 @Value 注释

    @Component
    public class Example {
    
        private LocalDate localDate;
    
        @Value("${property.name}")
        private void setLocalDate(String localDateStr) {
            if (localDateStr != null && !localDateStr.isEmpty()) {
                localDate = LocalDate.parse(localDateStr);
            }
        }
    }
    

    第二个是LocalDate/LocalDateTime

    public class Example {
        @Value("#{T(java.time.LocalDate).parse('${property.name}')}")
        private LocalDate localDate;
    }
    

    示例属性:

    property.name=2018-06-20
    

    【讨论】:

    • 第二个解决方案在日期为空时出错。有解决办法吗?
    • @Hackerman 设置默认值:@Value("#{T(java.time.LocalDate).parse('${property.name:2018-06-20}')}")私人 LocalDate localDate;
    【解决方案2】:

    Spring Boot 2.5,完美运行:

    application.yaml

    my.date: 2021-08-14
    my.time: "11:00"
    
    @Service
    public class TestService {
        @Value("${my.date}")
        @DateTimeFormat(pattern = "yyyy-MM-dd")
        LocalDate myDate;
    
        @Value("${my.time}")
        @DateTimeFormat(iso = DateTimeFormat.ISO.TIME)
        LocalTime myTime;
    }
    

    【讨论】:

      【解决方案3】:

      尝试将其添加到您的属性文件中:

      spring.jackson.date-format=com.fasterxml.jackson.databind.util.ISO8601DateFormat
      spring.jackson.time-zone=UTC
      

      并删除@DateTimeFormat 注释

      关于 LocalDate.now() 初始化。尝试以这种方式使用字段注入:

      @Value("${my.date}") LocalDate myDate = LocalDate.now();
      

      【讨论】:

        【解决方案4】:

        如果您还想指定日期格式,请在字段中使用以下内容:

        @Value("#{T(java.time.LocalDate).parse('${date.from.properties.file}', T(java.time.format.DateTimeFormatter).ofPattern('${date.format.from.properties.file}'))}")
        

        【讨论】:

          【解决方案5】:

          正如 Pavel 在其他回答中提到的,有两种方法。

          我提供了类似的两种方法,通过 OP 处理第二点的修改。

          如果属性不在属性文件中,参数应该是 使用 LocalDate.now() 创建的

          @Component
          public class Example {
          
          private LocalDate localDate;
          
          @Value("${property.name}")
          private void setLocalDate(String localDateStr) {
              if (localDateStr != null && !localDateStr.isEmpty()) {
                  localDate = LocalDate.parse(localDateStr, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
              }else{
                  localDate = LocalDate.now();
              }
          }
          }
          

          我更喜欢第二种方式...

          public class Example {
              @Value("#{T(java.time.LocalDate).parse('${property.name}', T(java.time.format.DateTimeFormatter).ofPattern('yyyy-MM-dd')) ?: T(java.time.LocalDate).now()}")
              private LocalDate localDate;
          }
          

          编辑:- 固定第二种方式

          @Value("#{ !('${date:}'.equals('')) ? T(java.time.LocalDate).parse('${date:}', T(java.time.format.DateTimeFormatter).ofPattern('MM-dd-yyyy')) " +
                  ":T(java.time.LocalDate).now()}")
          private LocalDate asOfDate;
          

          【讨论】:

          • 当我尝试上述方法时,我得到:IllegalArgumentException:无法解析占位符 'startDate' in value "#{T(java.time.LocalDateTime).parse('${startDate}', T( java.time.format.DateTimeFormatter).ofPattern('yyyy-MM-dd HH:mm:ss')) ?: T(java.time.LocalDateTime).now()}" 想法?
          • @JimM。修复了答案...请检查。
          【解决方案6】:

          首先,您可以创建一个转换器:

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

          您的配置类将自动使用它进行转换。

          第二次你可以这样做:

          if(my.date == null) iso = LocalDate.now()
          

          【讨论】:

            猜你喜欢
            • 2012-02-18
            • 1970-01-01
            • 1970-01-01
            • 2015-05-30
            • 2015-05-17
            • 1970-01-01
            • 2018-04-09
            • 2019-04-23
            相关资源
            最近更新 更多