Конфігурація Spring Boot yaml для списку рядків


149

Я намагаюся завантажити масив рядків з файлу application.yml. Це конфігурація:

ignore:
    filenames:
        - .DS_Store
        - .hg

Це клас:

@Value("${ignore.filenames}")
private List<String> igonoredFileNames = new ArrayList<>();

У цьому ж класі є й інші конфігурації, які завантажують просто чудово. У моєму файлі yaml немає вкладок. І все-таки я отримую таке виняток:

Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder 'ignore.filenames' in string value "${ignore.filenames}"

Відповіді:


71

Я здогадуюсь , що @Valueне вдається впоратися зі "складними" типами. Ви можете перейти з таким класом опори:

@Component
@ConfigurationProperties('ignore')
class IgnoreSettings {
    List<String> filenames
}

Зверніть увагу: Цей код Groovy - не Java - щоб приклад був коротким! Дивіться коментарі щодо порад, як прийняти.

Дивіться повний приклад https://github.com/christoph-frick/so-springboot-yaml-string-list


1
Ви можете зв'язати розділену комою коду @Value(до тих пір, поки конвертер зареєстрований, що це буде у Spring Boot, я думаю).
Дейв Сайер

2
Це налаштування рядків, але не налаштування Список <String>
Bahadır Yağan

1
Я не міг змусити його працювати @Configuration, але @Componentзамість цього зробив трюк.
Штійн Ван Баель

1
@cfrick так, це була єдина зміна, яку я вніс. Дивлячись на цілі обох анотацій, я б сказав, що @Componentце більше: stackoverflow.com/questions/12229282/…
Stijn Van Bael

2
Це виглядає так, що це обмеження щодо процесів весняного завантаження, які коментують
github.com/spring-projects/spring-boot/isissue/501

134

використовувати розділені комами значення в application.yml

ignoreFilenames: .DS_Store, .hg

код Java для доступу

@Value("${ignoreFilenames}")    
String[] ignoreFilenames

Це працює;)


Я сподівався, що це спрацює і в Dropwizard: '(хоча спасибі!
RST

1
Це мала бути найкращою відповіддю.
Мохамед Ельсайд

3
У моїх власних тестах це еквівалентно ".DS_Store, .hg", але не ".DS_Store", ".hg" - останній не вдається з "org.yaml.snakeyaml.parser.ParserException: під час розбору картографічного відображення". Тож, що ви насправді робите тут, - це надання властивості у вигляді єдиного рядка, розділеного комами (який Spring потім розбивається на масив чи список) замість масиву YAML. Це "працює", але не відповідає на початкове запитання. Я ще не знайшов спосіб проаналізувати масив YAML у властивості аннотованих бобів @Value.
Zirzirikos

38

З весняних завантажувальних документів https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html

Списки YAML представлені у вигляді ключів властивості з [індексом] переналагоджувачами, наприклад ця YAML:

my:
   servers:
       - dev.bar.com
       - foo.bar.com

Було б перетворено в ці властивості:

my.servers[0]=dev.bar.com
my.servers[1]=foo.bar.com

Щоб прив’язати до таких властивостей за допомогою утилітів Spring DataBinder (що це @ConfigurationPropertiesробить), вам потрібно мати властивість у цільовому бобі типу, java.util.Listі вам потрібно надати сеттер або ініціалізувати його із змінним значенням, наприклад, це пов'язує до властивостей вище. Ось як виглядатиме код питання.

@ConfigurationProperties(prefix="ignore")
public class Filenames {

    private List<String> ignoredFilenames = new ArrayList<String>();

    public List<String> getFilenames() {
        return this.ignoredFilenames;
    }
}

2
Це повинно працювати, BTW getXxx()необхідно, щоб він працював, і повинен використовувати a List, а не Set.
Ерік Ван

У ямлі список значень для ArrayList може бути списком, обмеженим комами. У моєму випадку у мене багато значень, тому компактний список чистіший, ніж елемент у рядку. Так у прикладі ви можете робити сервери: dev.bar.com, foo.bar.com
Violaman

25

Окрім відповіді Ахмета, ви можете додати розриви рядків до відокремленого рядка комою, використовуючи >символ.

application.yml :

ignoreFilenames: >
  .DS_Store, 
  .hg

Код Java :

@Value("${ignoreFilenames}")    
String[] ignoreFilenames;

Це добре працює до тих пір, поки у вас немає струнок (,).
Валентин Деспа

Це не працює для зчитування властивостей як масиву. Він читає їх як єдину струну.
Sree Lakshmi

6

Відповідь Ахмета передбачає, як призначити розділені комами значення масиву String.

Щоб використовувати вищевказану конфігурацію в різних класах, вам може знадобитися створити для цього геттери / сетери. Але якщо ви хочете один раз завантажити цю конфігурацію і продовжувати використовувати це як боб з анотацією Autowired, ось як я це здійснив:

В ConfigProvider.java

@Bean (name = "ignoreFileNames")
@ConfigurationProperties ( prefix = "ignore.filenames" )
public List<String> ignoreFileNames(){
    return new ArrayList<String>();
}

У позакласних заняттях:

@Autowired
@Qualifier("ignoreFileNames")
private List<String> ignoreFileNames;

Ви можете користуватися тим самим списком скрізь, використовуючи автопровід.


Це працює. У моєму випадку, хоч програма не вдалася, якщо я не додам @Configurationна початку класу в ConfigProvider.java. В іншому випадку я отримав Джерело, потрібен боб типу 'java.util.List', якого неможливо знайти.
Діана

3
@Value("#{'${your.elements}'.split(',')}")  
private Set<String> stringSet;

yml файл:

your:
 elements: element1, element2, element3

Ви можете грати з весняною силою набагато більше.


2

Ну, єдине, що я можу змусити його працювати, це так:

servers: >
    dev.example.com,
    another.example.com

@Value("${servers}")
private String[] array;

І не забувайте @Configuration над своїм класом ....

Без розлуки "," немає такої удачі ...

Працює теж (завантаження 1.5.8 версії)

servers: 
       dev.example.com,
       another.example.com

-1

У моєму випадку це була проблема синтаксису у файлі .yml. Я мав:

@Value("${spring.kafka.bootstrap-servers}")
public List<String> BOOTSTRAP_SERVERS_LIST;

і список у моєму файлі .yml:

bootstrap-servers:
  - s1.company.com:9092
  - s2.company.com:9092
  - s3.company.com:9092

не читає в поле @ Value-annotated. Коли я змінив синтаксис у файлі .yml на:

bootstrap-servers >
  s1.company.com:9092
  s2.company.com:9092
  s3.company.com:9092

це працювало чудово.


Спробувати це на Spring-boot 1.5, це не працює. Вам потрібна двокрапка після завантажувальних серверів
Taugenichts

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.