文字列のリストの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にあると思います)。
Dave Syer、2014年

2
これは、文字列の設定ではなく、リスト<文字列>の設定拾っている
Bahadırイェーガンを

1
私はそれをで動作させることができませんでした@Configurationが、@Component代わりにを使ってトリックを行いました。
Stijn Van Bael

1
@cfrickはい、私が行った唯一の変更でした。両方のアノテーションの目的を見ると、@Componentより適切だと思います。stackoverflow.com
questions


133

application.ymlでカンマ区切りの値を使用します

ignoreFilenames: .DS_Store, .hg

アクセス用のJavaコード

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

それは働いています;)


Dropwizardでもこれが機能することを期待していました:((感謝します!
RST

1
それが最良の答えだったはずです。
Mohamed Elsayed

3
私自身のテストでは、これは「.DS_Store、.hg」と同等ですが、「。DS_Store」、「。hg」とは異なります。後者は「org.yaml.snakeyaml.parser.ParserException:ブロックマッピングの解析中」で失敗します。したがって、ここで実際に行っているのは、YAML配列ではなく、単一のコンマ区切りの文字列(Springが配列またはリストに分割する)としてプロパティを提供することです。これは「機能します」が、元の質問には答えません。@Valueアノテーション付きBeanプロパティでYAML配列を解析する方法をまだ見つけていません。
ジルジリコ

38

Spring Boot docs https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.htmlから

YAMLリストは、[index]デリファレンスを持つプロパティキーとして表されます。たとえば、次のYAMLです。

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

これらのプロパティに変換されます:

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

Spring DataBinderユーティリティを使用してそのようなプロパティにバインドするには(これは何をするのか@ConfigurationProperties)、タイプのターゲットBeanにプロパティが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()が必要であり、Listではなくを使用する必要がありますSet
Eric Wang

yamlでは、ArrayListの値のリストはカンマ区切りのリストにすることができます。私の場合、私は多くの値を持っているので、コンパクトなリストは行ごとのアイテムよりもきれいです。したがって、この例では、次のサーバーを実行できます。dev.bar.com、foo.bar.com
Violaman

25

加えて、アフメットの答えあなたは昏睡状態に改行を追加することができます使用して文字列を区切り>記号を。

application.yml

ignoreFilenames: >
  .DS_Store, 
  .hg

Javaコード

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

文字列にコンマ(、)が含まれていない限り、これはうまく機能します。
バレンティンデスパ

これは、プロパティをarraylistとして読み取るには機能しません。それらを単一の文字列として読み取ります。
スリーラクシュミ

6

アフメットの答えは、カンマ区切りの値を文字列配列に割り当てる方法を提供します。

異なるクラスで上記の構成を使用するには、このためのゲッター/セッターを作成する必要があるかもしれません。しかし、この構成を一度ロードして、これをAutowiredアノテーション付きのBeanとして引き続き使用したい場合は、次のようにします。

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'タイプのBeanが必要です。
ダイアナ

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

ymlファイル:

your:
 elements: element1, element2, element3

Spring SPELで遊べる機能は他にもたくさんあります。


2

まあ、私がそれを機能させることができる唯一のものはそうです:

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

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

クラスの上の@Configurationを忘れないでください...

「、」の分離なしでは、そのような運はありません...

動作します(ブート1.5.8 versie)

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注釈付きフィールドを読み取っていませんでした。.ymlファイルの構文を次のように変更した場合:

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

それはうまくいきました。


これをスプリングブート1.5で試しても、機能しません。bootstrap-serversの後にコロンが必要
Taugenichts

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.