web-dev-qa-db-ja.com

リスト構造のSpring Boot Property Yml / Properties

私はこの問題の解決策として、stackoverflowとネット全体を調べました。ファイル内のリストとオブジェクト構造を含む投稿が私のユースケースに完全に一致しないため、私が見た解決策はありません。

これはyamlとしてのサンプルです

teddy.list:
    -
      name: Red
      price: Five
    -
      name: Blue
      price: One
    -
      name: Yellow
      price: Two
    -
      name: Green
      price: Three

これは、プロパティファイルと同じサンプルです。

teddy.list[0].name=Red
teddy.list[0].price=Five
teddy.list[1].name=Blue
teddy.list[1].price=One
teddy.list[2].name=Yellow
teddy.list[2].price=Two
teddy.list[3].name=Green
teddy.list[3].price=Three

設定のためにアプリケーションにteddy.ymlまたはteddy.propertiesファイルを提供できるようにしたいのですが。

これが私のクラスです:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;

@Configuration
@PropertySource(name = "props", value = "classpath:teddy.yml", ignoreResourceNotFound = false)
@ConfigurationProperties(prefix = "teddy")
public class TeddyBearConfig {

    @Autowired
    Environment env;

    @Value("${teddy.list}")
    private TeddyBear[] teddyBears;

    public TeddyBear[] getTeddyBears() {
        return teddyBears;
    }

    public void setTeddyBears(TeddyBear[] teddyBears) {
        this.teddyBears = teddyBears;
    }

    public static class TeddyBear {
        private String name;
        private String price;

        public TeddyBear() {

        }

        public TeddyBear(String name, String price) {
            this.name = name;
            this.price = price;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getPrice() {
            return price;
        }

        public void setPrice(String price) {
            this.price = price;
        }
    }
}

私はこの設定を試し、環境を使用してプロパティにアクセスし、接頭辞を削除して、「PropertySourcesPlaceholderConfigurer」のBeanを宣言しました。

現在のコードでは、Java.lang.stringをTeddyBearクラスに変換できないため、SpringはIllegalStateExceptionをスローします。

7
GSUgambit

これはうまくいくはずです。

@Configuration
@PropertySource(name = "props", value = "classpath:teddy.properties", ignoreResourceNotFound = false)
@ConfigurationProperties(prefix = "teddy")
public class TeddyBearConfig {

  private List<TeddyBear> list;

  public List<TeddyBear> getList() {
    return list;
  }

  public void setList(List<TeddyBear> list) {
    this.list = list;
  }

  public static class TeddyBear {
    private String name;
    private String price;

    public TeddyBear() {

    }

    public TeddyBear(String name, String price) {
      this.name = name;
      this.price = price;
    }

    public String getName() {
      return name;
    }

    public void setName(String name) {
      this.name = name;
    }

    public String getPrice() {
      return price;
    }

    public void setPrice(String price) {
      this.price = price;
    }
  }
}

更新

上記のコードは、上記で指定したプロパティファイルに対して機能します。
ymlファイルを使用する場合は、使用できます。しかし、いくつかの点があります。
1。あなたのyml構造は正しくありません、それはこのようになるはずです

teddy:
  list:
    -
      name: Red
      price: Five
    -
      name: Blue
      price: One
    -
      name: Yellow
      price: Two
    -
      name: Green
      price: Three

2. yml構造(およびTeddyBearConfigのファイル名も)を修正した後、起動時にspringbootが問題を起こさないことがわかりますが、TeddBearConfigのリスト変数はnullになります。これは、springbootが@PropertySourceを通じてymlファイルを処理する方法のバグです。

3.このymlコンテンツをapplication.ymlに移動し、構成ファイルの@PropertySource行を削除すると、すべてが完全に正常に動作することがわかります。

7
pvpkiran

気を付けて。上記のSpringバージョンによっては、コードが機能しない場合があります。

これかもしれない!

private List<TeddyBear> list = new ArrayList<>;

public List<TeddyBear> getList() {
  return list;
}

トリックは、SpringファクタリングがgetList()を呼び出し、TeddyBearsを新しいArrayListに追加することです。 nullポインターでは、追加するものはありません。ゲッターを捨てる。使用されていない。

あなたはさらに必要です:

@Autowired
TeddyBearConfig teddyBearConfig;

最後の発言:SpringBootTestでテストする場合は、さらにいくつかのヒントが必要になる場合があります。

コンテキストとしてテストアプリを提供します。よりエレガントな方法があるはずですが、私はこのようにしました:

@SpringBootTest(classes = {TestApplication.class,..

@SpringBootApplication
public class TestApplication {
   public static void main(String[] args) throws Throwable {
      SpringApplication.run(TestApplication.class, args);
  }
 }

app.propertiesがTestSourcesパスの下にある場合は、TestPropertySourceを使用します。

@TestPropertySource(locations="classpath:application.properties")
0
Roland Roos

ConfigurationPropertiesアノテーションを使用しているので、代わりに

@Value("${teddy.list}")
private TeddyBear[] teddyBears;

あなたは直接行うことができます

private List<TeddyBear> list;

@Valueアノテーションは不要です。

また、変数名はlistにする必要があります。これは、ymlに指定したものだからです。

0
Yogesh Badke