Spring boot 2 Преобразование продолжительности java 8 application.properties

Мне нужно определить значение Duration (spring.redis.timeout) с помощью application.properties.

Я пытался использовать одну точку, определенную в документации по загрузке Spring:

В Spring Boot есть специальная поддержка выражения длительности. Если вы предоставляете свойство java.time.Duration, в свойствах приложения доступны следующие форматы:

Обычное длинное представление (с использованием миллисекунд в качестве единицы по умолчанию, если не указано @DurationUnit) Стандартный формат ISO-8601, используемый java.util.Duration Более читаемый формат, в котором значение и единица измерения связаны (например, 10 с означает 10 секунд)

Когда я использую spring.redis.timeout=3s, загрузочное приложение Spring выдает это исключение:

Не удается преобразовать значение типа «java.lang.String» в требуемый тип «java.time.Duration»: не найдены подходящие редакторы или стратегия преобразования

Как лучше всего установить правильное значение свойства Duration в application.properties с последним выпуском Spring boot 2?


person CRISTIAN ROMERO MATESANZ    schedule 13.08.2018    source источник
comment
stackoverflow.com/questions/47734728/   -  person pvpkiran    schedule 13.08.2018
comment
Итак, согласно гитхабу spring-boot. Например, невозможно использовать Duration и @Value. Они ожидали этого для весенней загрузки 2.1.0: github.com/spring- проекты/весенняя загрузка/проблемы/13237   -  person Brother    schedule 13.08.2018
comment
Я опубликовал решение, позволяющее использовать @value.   -  person CRISTIAN ROMERO MATESANZ    schedule 13.08.2018
comment
github.com/spring- проекты/весенняя загрузка/вики/.   -  person Wilder Valera    schedule 28.09.2018
comment
Пожалуйста, обратитесь к моему решению stackoverflow.com/questions/67722926/   -  person chandra kumar    schedule 27.05.2021


Ответы (6)


Любое свойство продолжительности может быть введено через файлы .properties или .yml. Все, что вам нужно сделать, это использовать правильное форматирование.

Если вы хотите ввести продолжительность 5 секунд, она должна быть определена как PT5S или pt5s или PT5s

  • регистр букв не имеет значения, поэтому вы используете любую комбинацию, которая читабельна для вас
  • обычно все используют все заглавные буквы

Другие примеры

PT1.5S       = 1.5 Seconds
PT60S        = 60 Seconds
PT3M         = 3 Minutes
PT2H         = 2 Hours
P3DT5H40M30S = 3Days, 5Hours, 40 Minutes and 30 Seconds

Вы также можете использовать знаки +ve и -ve для обозначения положительного или отрицательного периода времени.

  • Вы можете отрицать только одну сущность, например: PT-3H30M = -3 часа, +30 минут, в основном -2,5 часа.
  • Или Вы можете отрицать всю сущность: -PT3H30M = -3 часа, -30 минут, в основном -3,5 часа.
  • Double negative works here too: -PT-3H+30M = +3 Hours, -30 Minutes, basically +2.5Hours



Голосуйте за, если это работает для вас или вам нравится объяснение. Спасибо,

person Rituraj    schedule 16.06.2020
comment
Spring Boot также поддерживает простое форматирование длительности: 60 сек., 5 м., 2 ч. - person M. Justin; 18.12.2020
comment
Просто убедитесь, что у вас нет конечных пробелов. - person Vinagy; 26.02.2021
comment
Это не работает для меня с Spring Boot 2.3.2.RELEASE w java 11. Получение исключения IllegalStateException Не удается преобразовать значение типа «java.lang.String» в требуемый тип «java.time.Duration»: не найдены подходящие редакторы или стратегия преобразования Использование: @Value(${foo.start.window:PT2H}) private Duration fooStartWindow; - person JohnC; 16.05.2021
comment
@JohnC - я считаю, что вы используете это неправильно. Вы можете вставить фрагмент кода здесь? Технически код будет @Value("${foo.start.window:startWinPeriod}") private Duration fooStartWindow;, и в свойстве вашего приложения у вас будет что-то вроде foo.start.window.startWinPeriod=PT2H или файла yml, как показано ниже foo: start: window startWinPeriod:PT2H - person Rituraj; 17.05.2021

Можно использовать нотацию @Value с языком Spring Expression.

@Value("#{T(java.time.Duration).parse('${spring.redis.timeout}')}")
private Duration timeout;
person Serge    schedule 20.03.2019
comment
Spring Boot теперь поддерживает Duration напрямую (без использования SEL). Протестировано на Spring Boot 2.1.9.RELEASE. - person Jardo; 16.10.2019

Продолжительность в данный момент (Spring-Boot 2.0.4.RELEASE) нельзя использовать вместе с нотацией @Value, но можно использовать с @ConfigurationProperties

Для Redis у вас есть RedisProperties, и вы можете использовать конфигурацию:

spring.redis.timeout=5s

И:

@SpringBootApplication
public class DemoApplication {

  @Autowired
  RedisProperties redisProperties;

  public static void main(String[] args) {
    SpringApplication.run(DemoApplication.class, args);
  }

  @PostConstruct
  void init() {
    System.out.println(redisProperties.getTimeout());
  }
}

Он напечатан (анализируется как 5s):

PT5S

https://docs.oracle.com/javase/8/docs/api//java/time/Duration.html#parse-java.lang.CharSequence-

person Brother    schedule 13.08.2018

Spring Boot пытается привести свойства внешнего приложения к нужному типу, когда он привязывается к bean-компонентам @ConfigurationProperties. Если вам нужно преобразование пользовательского типа, вы можете предоставить bean-компонент ConversionService (с bean-компонентом с именем convertService)

См.: https://docs.spring.io/spring-boot/docs/2.0.4.RELEASE/reference/htmlsingle/#boot-features-external-config-conversion

Создайте новый bean-компонент ApplicationConversionService (он должен называться convertService ). Вот мой код, протестированный с Spring boot 2.0.4:

@Configuration
public class Conversion {

@Bean
public ApplicationConversionService conversionService()
{
    final ApplicationConversionService applicationConversionService = new ApplicationConversionService();
    return applicationConversionService;
}

Вот пример проекта, использующего этот подход:

https://github.com/cristianprofile/spring-data-redis-lettuce

person CRISTIAN ROMERO MATESANZ    schedule 13.08.2018
comment
в 2.1.x это не понадобится. см. github.com/spring -проекты/весенняя загрузка/вики/ - person Wilder Valera; 28.09.2018
comment
Я попробую поддержку Context ApplicationConversionService (2.1). ApplicationConversionService теперь зарегистрирован по умолчанию в Environment и BeanFactory, созданных SpringApplication. Это позволяет вам использовать преобразователи приложений непосредственно с основными элементами Spring Framework, такими как аннотация @Value: @Value(${my.duration:10s}) private Duration duration; - person CRISTIAN ROMERO MATESANZ; 01.10.2018

Если ваша версия Spring-Boot или ее зависимости не помещают ApplicationConversionService в контекст (а Spring-Boot не делает этого до версии 2.1), вы можете явно указать его.

@Bean
public ConversionService conversionService() {
    return ApplicationConversionService.getSharedInstance();
}

Он вызывает Duration.parse, поэтому вы можете использовать PT3S, PT1H30M и т. д. в файлах свойств.

person Max    schedule 06.09.2019

Я получал эту ошибку, но только во время тестирования, в остальном bean-компонент, использующий @Value-аннотированный Duration, работал. Оказалось, что мне не хватало аннотации @SpringBootTest в классе тестового примера (и зависимости spring-boot-test, которая ее предоставляет), и это приводило к тому, что для использования было доступно только подмножество стандартных преобразователей.

person Donal Fellows    schedule 10.06.2021