如何以 ISO8601 格式将 Spring Boot 解析属性绑定到 LocalTime?

Wim*_*uwe 2 java spring spring-boot

我有一个使用@ConfigurationProperties组件的 Spring Boot 2.2.6 应用程序,如下所示:

@Component
@ConfigurationProperties("myapplication")
public class MyApplicationSettings {
    private LocalTime startOfDay;

    // getter and setters here
}
Run Code Online (Sandbox Code Playgroud)

我的集成测试突然开始在 Jenkins 上失败,但在本地运行良好。异常显示如下:

Description:

Failed to bind properties under 'myapplication.start-of-day' to java.time.LocalTime:

    Property: myapplication.start-of-day
    Value: 06:00
    Origin: class path resource [application-integration-test.properties]:29:62
    Reason: failed to convert java.lang.String to java.time.LocalTime

Action:

Update your application's configuration
Run Code Online (Sandbox Code Playgroud)

完整的异常跟踪的根本原因是:

Caused by: java.time.format.DateTimeParseException: Text '06:00' could not be parsed at index 5
    at java.base/java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:2046)
    at java.base/java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1948)
    at java.base/java.time.LocalTime.parse(LocalTime.java:463)
    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:217)
Run Code Online (Sandbox Code Playgroud)

在对代码进行了一些挖掘之后,我发现 Spring 将使用默认语言环境来解析LocalTime. 由于我的本地机器使用 24 小时制,它可以工作。构建服务器使用 12 小时语言环境,因此无法解析字符串,因为没有 am/pm 指示。

我的问题:

如何配置 Spring Boot 将配置属性解析为 ISO-8601 格式,独立于 JVM 的默认语言环境?

我还检查了文档,但“属性转换”一章没有提到LocalTime(或LocalDate

Mar*_*nik 5

解决方案应包括以下步骤:

  1. 创建@ConfigurationProperties带注释的类LocalTime字段(在你的情况MyApplicationSettings),并注册它@Configuration@EnableConfigurationProperties(MyApplicationSettings.class)
  2. application.properties定义值中:
myapplication.startOfDay=06:00:00
Run Code Online (Sandbox Code Playgroud)
  1. 创建一个特殊的转换器并确保它被 Spring Boot 应用程序扫描和加载。实际解析的逻辑当然可以不同,实现你想要的任何东西,任何特定的格式,语言环境 - 无论如何:
@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"));
    }
}
Run Code Online (Sandbox Code Playgroud)
  1. 现在类中的所有LocalTime条目@ConfigurationProperties都将通过此转换器。

  • 谢谢,确实有效。我做了两处更改:“source”永远不能为“null”,因此可以删除该检查。我使用了 `LocalTime.parse(source)` 因为它默认为我想要的 ISO-8601 格式。 (2认同)