Cấu hình Spring Boot yaml cho danh sách các chuỗi


149

Tôi đang cố gắng tải một chuỗi các chuỗi từ tệp application.yml. Đây là cấu hình:

ignore:
    filenames:
        - .DS_Store
        - .hg

Đây là lớp học:

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

Có các cấu hình khác trong cùng một lớp chỉ tải tốt. Không có tab trong tập tin yaml của tôi. Tôi vẫn nhận được ngoại lệ sau:

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

Câu trả lời:


71

Tôi đoán là, @Valuekhông thể đối phó với các loại "phức tạp". Bạn có thể đi với một lớp chống đỡ như thế này:

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

Xin lưu ý: Mã này là Groovy - không phải Java - để giữ ví dụ ngắn! Xem các ý kiến ​​cho lời khuyên làm thế nào để áp dụng.

Xem ví dụ đầy đủ https://github.com/christoph-frick/so-springboot-yaml-opes-list


1
Bạn có thể liên kết một dấu phẩy được phân tách bằng @Value(miễn là một trình chuyển đổi được đăng ký, nó sẽ có trong Spring Boot tôi nghĩ).
Dave Syer

2
Nó đang chọn cài đặt chuỗi nhưng không cài đặt Danh sách <Chuỗi>
Bahadır Yağan

1
Tôi không thể làm cho nó hoạt động được @Configuration, nhưng @Componentthay vào đó sử dụng mánh khóe.
Stijn Van Bael

1
@cfrick vâng, đó là thay đổi duy nhất tôi đã thực hiện. Nhìn vào mục đích của cả hai chú thích, tôi sẽ nói @Componentlà phù hợp hơn: stackoverflow.com/questions/12229282/
Kẻ

2
Điều này có vẻ như là một hạn chế với các quy trình khởi động mùa xuân mà chú thích - github.com/spring-projects/spring-boot/issues/501
wontondon

133

sử dụng các giá trị được phân tách bằng dấu phẩy trong application.yml

ignoreFilenames: .DS_Store, .hg

mã java để truy cập

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

Nó đang làm việc ;)


Tôi đã hy vọng điều này cũng sẽ hoạt động trong Dropwizard: '(mặc dù cảm ơn!
RST

1
Đó nên là câu trả lời tốt nhất.
Mohamed Elsayed

3
Trong các thử nghiệm của riêng tôi, điều này tương đương với ".DS_Store, .hg" nhưng không phải ".DS_Store", ".hg" - sau này thất bại với "org.yaml.snakeyaml.parser.ParserException: trong khi phân tích ánh xạ khối". Vì vậy, những gì bạn thực sự đang làm ở đây là cung cấp thuộc tính dưới dạng một chuỗi được phân tách bằng dấu phẩy (mà Spring sau đó phân tách thành một mảng hoặc danh sách) thay vì một mảng YAML. Điều này "hoạt động" nhưng không trả lời câu hỏi ban đầu. Tôi vẫn chưa tìm được cách phân tích một mảng YAML trong thuộc tính bean có chú thích @Value.
Zirzirikos

38

Từ tài liệu khởi động mùa xuân https://docs.spring.io/spring-boot/docs/civerse/reference/html/boot-features-external-config.html

Danh sách YAML được biểu diễn dưới dạng các khóa thuộc tính với các chỉ số [chỉ mục], ví dụ YAML này:

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

Sẽ được chuyển đổi thành các thuộc tính này:

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

Để liên kết với các thuộc tính như thế bằng cách sử dụng các tiện ích Spring DataBinder (đó là những gì @ConfigurationPropertiesbạn cần), bạn cần phải có một thuộc tính trong bean mục tiêu loại java.util.Listvà bạn cần cung cấp một setter hoặc khởi tạo nó với một giá trị có thể thay đổi, ví dụ: điều này sẽ liên kết để các thuộc tính trên. Đây là mã của câu hỏi sẽ như thế nào.

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

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

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

2
Điều này nên hoạt động, BTW getXxx()là cần thiết để nó hoạt động, và phải sử dụng một List, không Set.
Eric Wang

Trong yaml, danh sách các giá trị cho ArrayList có thể là danh sách được phân tách bằng dấu phẩy. Trong trường hợp của tôi, tôi có nhiều giá trị, vì vậy một danh sách nhỏ gọn sẽ sạch hơn một mục trên mỗi dòng. Vì vậy, trong ví dụ này, bạn có thể thực hiện các máy chủ: dev.bar.com, foo.bar.com
Violaman

25

Ngoài câu trả lời của Ahmet, bạn có thể thêm ngắt dòng vào chuỗi phân tách hôn mê bằng cách sử dụng> ký hiệu.

ứng dụng.yml :

ignoreFilenames: >
  .DS_Store, 
  .hg

Mã Java :

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

Điều này hoạt động tốt miễn là bạn không có thêm dấu phẩy (,) trong chuỗi của mình.
Valentin Despa

Điều này không hoạt động để đọc các thuộc tính như danh sách mảng. Nó đọc chúng dưới dạng Chuỗi đơn.
Sree Lakshmi

6

Câu trả lời của Ahmet cung cấp về cách gán các giá trị được phân tách bằng dấu phẩy cho mảng Chuỗi.

Để sử dụng cấu hình trên trong các lớp khác nhau, bạn có thể cần phải tạo getters / setters cho việc này .. Nhưng nếu bạn muốn tải cấu hình này một lần và tiếp tục sử dụng nó như một bean với chú thích Autowired, đây là cách tôi đã hoàn thành:

Trong ConfigProvider.java

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

Trong các lớp học bên ngoài:

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

bạn có thể sử dụng cùng một danh sách ở mọi nơi khác bằng cách tự động.


Điều đó làm việc. Trong trường hợp của tôi mặc dù ứng dụng thất bại, trừ khi tôi thêm @Configurationvào đầu lớp ConfigProvider.java. Nếu không, tôi đã nhận được Nguồn yêu cầu một loại đậu 'java.util.List' không thể tìm thấy.
Diana

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

tập tin yml:

your:
 elements: element1, element2, element3

Có rất nhiều bạn có thể chơi với spEL mùa xuân.


2

Chà, điều duy nhất tôi có thể làm cho nó hoạt động là như vậy:

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

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

Và đừng quên @Configuration trên lớp của bạn ....

Không có sự tách biệt ",", không có may mắn như vậy ...

Hoạt động quá (boot 1.5.8 Versie)

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

-1

Trong trường hợp của tôi, đây là một vấn đề cú pháp trong tệp .yml. Tôi đã có:

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

và danh sách trong tệp .yml của tôi:

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

đã không đọc vào trường chú thích giá trị @. Khi tôi thay đổi cú pháp trong tệp .yml thành:

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

nó hoạt động tốt


Thử cái này trên spring-boot 1.5 nhưng không được. Bạn cần một dấu hai chấm sau bootstrap-server
Taugenichts

-2
@Value("${your.elements}")    
private String[] elements;

tập tin yml:

your:
 elements: element1, element2, element3

1
Làm thế nào là hình thức khác nhau câu trả lời của Ahmet? stackoverflow.com/a/41462567/2065796
Sasha Shpota

1
Trả lời đã được cung cấp. Trả lời chỉ vì lợi ích của các điểm không làm tăng giá trị
Deepak
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.