Konfigurasi yaml Spring Boot untuk daftar string


149

Saya mencoba memuat array string dari file application.yml. Ini adalah konfigurasi:

ignore:
    filenames:
        - .DS_Store
        - .hg

Ini kelasnya:

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

Ada konfigurasi lain di kelas yang sama yang memuat dengan baik. Tidak ada tab di file yaml saya. Masih saya mendapatkan pengecualian berikut:

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

Jawaban:


71

Dugaan saya adalah, bahwa @Valuetidak dapat mengatasi jenis "kompleks". Anda bisa menggunakan kelas prop seperti ini:

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

Harap dicatat: Kode ini Groovy - bukan Java - untuk membuat contoh singkat! Lihat komentar untuk tips bagaimana mengadopsi.

Lihat contoh lengkap https://github.com/christoph-frick/so-springboot-yaml-string-list


1
Anda dapat mengikat koma-terpisah dengan @Value(selama konverter terdaftar, yang akan di Spring Boot kurasa).
Dave Syer

2
Ini mengambil pengaturan string tetapi tidak
Mendaftar

1
Saya tidak bisa membuatnya bekerja @Configuration, tetapi menggunakan @Componentbukan melakukan trik.
Stijn Van Bael

1
@cfrick ya itu satu-satunya perubahan yang saya buat. Melihat tujuan kedua penjelasan, saya akan mengatakan @Componentlebih tepat: stackoverflow.com/questions/12229282/…
Stijn Van Bael

2
Sepertinya ini adalah batasan dengan proses boot musim semi yang anotasi - github.com/spring-projects/spring-boot/issues/501
wontondon

134

gunakan nilai yang dipisahkan koma di application.yml

ignoreFilenames: .DS_Store, .hg

kode java untuk akses

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

Ini bekerja ;)


Saya berharap ini akan bekerja di Dropwizard juga: '(terima kasih!
RST

1
Itu seharusnya menjadi jawaban terbaik.
Mohamed Elsayed

3
Dalam pengujian saya sendiri, ini setara dengan ".DS_Store, .hg" tetapi tidak ".DS_Store", ".hg" - yang terakhir gagal dengan "org.yaml.snakeyaml.parser.ParserException: saat menguraikan pemetaan blok". Jadi apa yang sebenarnya Anda lakukan di sini adalah menyediakan properti sebagai string yang dipisahkan oleh koma (yang Spring kemudian pisahkan menjadi array atau daftar) alih-alih array YAML. Ini "berhasil" tetapi tidak menjawab pertanyaan awal. Saya belum menemukan cara untuk mem-parse array YAML di properti bean beranotasi @Value.
Zirzirikos

38

Dari spring boot docs https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html

Daftar YAML direpresentasikan sebagai kunci properti dengan [index] dereferencers, misalnya YAML ini:

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

Akan diubah menjadi properti ini:

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

Untuk mengikat properti seperti itu menggunakan utilitas Spring DataBinder (yang berfungsi apa @ConfigurationProperties), Anda perlu memiliki properti di kacang tipe target java.util.Listdan Anda perlu menyediakan setter, atau menginisialisasi dengan nilai yang bisa berubah, misalnya ini akan mengikat ke properti di atas. Di sini akan terlihat seperti apa kode pertanyaan itu.

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

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

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

2
Ini harus berfungsi, BTW getXxx()diperlukan agar bisa berfungsi, dan harus menggunakan List, bukan Set.
Eric Wang

Di yaml, daftar nilai untuk ArrayList bisa berupa daftar yang dibatasi koma. Dalam kasus saya, saya memiliki banyak nilai, jadi daftar ringkas lebih bersih daripada item per baris. Jadi dalam contoh, Anda dapat melakukan server: dev.bar.com, foo.bar.com
Violaman

Bisakah yaml dimuat dari file properti seperti ini servers: ${my.servers}:? Untuk masuk my.servers[0]dan my.servers[1]masuk ke ubi jalar? Saya mencoba untuk memiliki konfigurasi panggung tergantung
ochs.tobi

25

Selain jawaban Ahmet, Anda dapat menambahkan jeda baris ke string yang dipisahkan koma menggunakan >simbol.

application.yml :

ignoreFilenames: >
  .DS_Store, 
  .hg

Kode Java :

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

Ini berfungsi dengan baik selama Anda tidak memiliki koma lagi (,) di string Anda.
Valentin Despa

Ini tidak berfungsi untuk membaca properti sebagai daftar array. Bunyinya sebagai String tunggal.
Sree Lakshmi

6

Jawaban Ahmet memberikan cara menetapkan nilai yang dipisahkan koma ke array String.

Untuk menggunakan konfigurasi di atas dalam kelas yang berbeda, Anda mungkin perlu membuat getter / setter untuk ini .. Tetapi jika Anda ingin memuat konfigurasi ini sekali dan terus menggunakan ini sebagai kacang dengan anotasi Autowired, berikut adalah cara yang saya lakukan:

Di ConfigProvider.java

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

Di kelas luar:

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

Anda dapat menggunakan daftar yang sama di mana pun dengan autowiring.


Itu bekerja. Dalam kasus saya meskipun aplikasi gagal, kecuali saya tambahkan @Configurationdi awal kelas ConfigProvider.java. Kalau tidak, saya mendapatkan Sumber diperlukan kacang jenis 'java.util.List' yang tidak dapat ditemukan.
Diana

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

file yml:

your:
 elements: element1, element2, element3

Ada banyak lagi yang bisa kamu mainkan dengan spring spEL.


2

Ya, satu-satunya hal yang bisa saya lakukan adalah:

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

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

Dan jangan lupa konfigurasi @ di atas kelas Anda ....

Tanpa pemisahan ",", tidak ada keberuntungan seperti itu ...

Bekerja juga (boot 1.5.8 versie)

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

-1

Dalam kasus saya ini adalah masalah sintaksis dalam file .yml. Saya punya:

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

dan daftar di file .yml saya:

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

tidak membaca bidang isian @ Nilai. Ketika saya mengubah sintaks dalam file .yml ke:

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

itu bekerja dengan baik.


Mencoba ini pada spring-boot 1.5 ini tidak berhasil. Anda memerlukan titik dua setelah bootstrap-server
Taugenichts

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.