繁体   English   中英

使用 application.properties 中的 spring 表达式语言解析 LocalTime

[英]Parse LocalTime using spring expression language from application.properties

我正在尝试使用以下代码从 spring 的 application.properties 解析 LocalTime:

@Value("#{ T(java.time.LocalTime).parse('${app.myDateTime}')}")
private LocalTime myDateTime;

在 application.properties 我定义了这样的属性:

app.myDateTime=21:45:00

错误信息:

Failed to bind properties under 'app.my-date-time' to java.time.LocalTime:

Property: app.my-date-time
Value: 21:45:00
Origin: class path resource [application.properties]:44:15
Reason: failed to convert java.lang.String to @org.springframework.beans.factory.annotation.Value java.time.LocalTime

知道我做错了什么吗? 谢谢你。

调试模式下的错误:

Caused by: org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [java.time.LocalTime] for value '21:45:00'; nested exception is java.lang.IllegalArgumentException: Parse attempt failed for value [21:45:00]
    at org.springframework.core.convert.support.ConversionUtils.invokeConverter(ConversionUtils.java:47)
    at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:191)
    at org.springframework.boot.context.properties.bind.BindConverter$CompositeConversionService.convert(BindConverter.java:170)
    at org.springframework.boot.context.properties.bind.BindConverter.convert(BindConverter.java:96)
    at org.springframework.boot.context.properties.bind.BindConverter.convert(BindConverter.java:88)
    at org.springframework.boot.context.properties.bind.Binder.bindProperty(Binder.java:313)
    at org.springframework.boot.context.properties.bind.Binder.bindObject(Binder.java:258)
    at org.springframework.boot.context.properties.bind.Binder.bind(Binder.java:214)
    ... 210 common frames omitted
Caused by: java.lang.IllegalArgumentException: Parse attempt failed for value [21:45:00]
    at org.springframework.format.support.FormattingConversionService$ParserConverter.convert(FormattingConversionService.java:206)
    at org.springframework.core.convert.support.ConversionUtils.invokeConverter(ConversionUtils.java:41)
    ... 217 common frames omitted
Caused by: java.time.format.DateTimeParseException: Text '21:45:00' could not be parsed at index 5
    at java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:1949)
    at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1851)
    at java.time.LocalTime.parse(LocalTime.java:441)
    at org.springframework.format.datetime.standard.TemporalAccessorParser.parse(TemporalAccessorParser.java:72)
    at org.springframework.format.datetime.standard.TemporalAccessorParser.parse(TemporalAccessorParser.java:46)
    at org.springframework.format.support.FormattingConversionService$ParserConverter.convert(FormattingConversionService.java:200)
    ... 218 common frames omitted

选项 1 - 使用@ConfigurationPropertiesBinding

如果您使用@ConfigurationProperties加载属性,您可以使用@ConfigurationPropertiesBinding将自定义转换器绑定到 Spring:

@Component
@ConfigurationPropertiesBinding
public class LocalTimeConverter implements Converter<String, LocalTime> {
  @Override
  public LocalTime convert(String source) {
      if(source==null){
          return null;
      }
      return LocalTime.parse(source, DateTimeFormatter.ofPattern("HH:mm:ss"));
  }
}

在此处输入图像描述

选项 2 - 使用@Value

如果您宁愿坚持使用@Value ,那么您非常接近:

@Value("#{T(java.time.LocalTime).parse('${app.myDateTime}', T(java.time.format.DateTimeFormatter).ofPattern('HH:mm:ss'))}")

有关选项列表,请参阅https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html

资料来源:

要将日期注入@Value,使用 Spring 表达式语言 (SpEL),例如:

@Value(“#{new java.text.SimpleDateFormat(‘${aTimeFormat}’).parse(‘${aTimeStr}’)}”)
Date myDate;

在您的情况下,您直接注入 Date 值而不提供格式化程序,因此它不知道要解析为什么格式,使用该格式定义一个新属性并使用该格式化程序来解析上面的示例中的值,它将得到注入。 您的 application.properties 属性应如下所示:

aTimeStr=21:16:46
aTimeFormat=HH:mm:ss

默认情况下, Spring 使用本地化的非iso FormatStyle.SHORT进行时间格式化,除非它以某种方式被覆盖。 所以我怀疑你可以使用09:45 PM作为属性值,但这不是你想要的。

但正如我已经提到的,您可以使用DateTimeFormatterRegistrar机制全局覆盖 Spring 预期的模式。

或者,您也可以在 LocalTime LocalTime myDateTime字段上使用@DateTimeFormat注释。 使用此注解,您可以通过三种方式指定所需的格式,即styleisopattern 在您的情况下, iso = DateTimeFormat.ISO.TIME会起作用。 因此,您的代码将如下所示:

@Value("${app.myDateTime}")
@DateTimeFormat(iso = DateTimeFormat.ISO.TIME)
private LocalTime myDateTime;

请注意,这三个属性是互斥的(请参阅提供的链接中的 javadoc):

每个属性是互斥的,所以每个注解实例只设置一个属性

我已经用 jdk-11 在 spring boot-2.1.5 上对此进行了测试

@Value("#{ T(java.time.LocalTime).parse('${app.myDateTime}',T(java.time.format.DateTimeFormatter).ISO_LOCAL_TIME)}")
private LocalTime timeValue;   //21:45

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM