私のSpring Bootアプリには、次のコンテンツを含むapplication.yaml設定ファイルがあります。チャネル構成のリストを含む構成オブジェクトとして注入します。
available-payment-channels-list:
xyz: "123"
channelConfigurations:
-
name: "Company X"
companyBankAccount: "1000200030004000"
-
name: "Company Y"
companyBankAccount: "1000200030004000"
@ConfigurationオブジェクトPaymentConfigurationオブジェクトのリストを追加したい:
@ConfigurationProperties(prefix = "available-payment-channels-list")
@Configuration
@RefreshScope
public class AvailableChannelsConfiguration {
private String xyz;
private List<ChannelConfiguration> channelConfigurations;
public AvailableChannelsConfiguration(String xyz, List<ChannelConfiguration> channelConfigurations) {
this.xyz = xyz;
this.channelConfigurations = channelConfigurations;
}
public AvailableChannelsConfiguration() {
}
// getters, setters
@ConfigurationProperties(prefix = "available-payment-channels-list.channelConfigurations")
@Configuration
public static class ChannelConfiguration {
private String name;
private String companyBankAccount;
public ChannelConfiguration(String name, String companyBankAccount) {
this.name = name;
this.companyBankAccount = companyBankAccount;
}
public ChannelConfiguration() {
}
// getters, setters
}
}
これを、@ Autowiredコンストラクターを使用して通常のBeanとして注入しています。 xyzの値は正しく設定されていますが、Springがyamlを解析してオブジェクトのリストにしようとすると、
nested exception is Java.lang.IllegalStateException:
Cannot convert value of type [Java.lang.String] to required type
[io.example.AvailableChannelsConfiguration$ChannelConfiguration]
for property 'channelConfigurations[0]': no matching editors or
conversion strategy found]
ここで何が間違っているのか?
理由はどこかにあるに違いありません。設定なしですぐに使えるSpring Boot 1.2.2のみを使用すると、Just Worksになります。このレポをご覧ください-それを破ることができますか?
https://github.com/konrad-garus/so-yaml
YAMLファイルは、貼り付けたとおりに見えますか?余分な空白、文字、特殊文字、インデントの間違いなどはありませんか?あなたが期待しているものの代わりに使用されている検索パスの他の場所に別のファイルがある可能性はありますか?
RefreshScope
を@Configuration
と共に使用すると問題が発生します。 このgithubの問題 をご覧くださいクラスを次のように変更します。
@ConfigurationProperties(prefix = "available-payment-channels-list")
@Configuration
public class AvailableChannelsConfiguration {
private String xyz;
private List<ChannelConfiguration> channelConfigurations;
// getters, setters
public static class ChannelConfiguration {
private String name;
private String companyBankAccount;
// getters, setters
}
}
私はこの記事や他の多くの記事を参照しましたが、明確な簡潔な回答は見つかりませんでした。私は、このスレッドからの参照を次のようにして得た発見を提供しています。
スプリングブートバージョン:1.3.5.RELEASE
Spring-Coreバージョン:4.2.6.RELEASE
依存関係管理:Brixton.SR1
以下は関連するyamlの抜粋です。
tools:
toolList:
-
name: jira
matchUrl: http://someJiraUrl
-
name: bamboo
matchUrl: http://someBambooUrl
Tools.classを作成しました:
@Component
@ConfigurationProperties(prefix = "tools")
public class Tools{
private List<Tool> toolList = new ArrayList<>();
public Tools(){
//empty ctor
}
public List<Tool> getToolList(){
return toolList;
}
public void setToolList(List<Tool> tools){
this.toolList = tools;
}
}
Tool.classを作成しました。
@Component
public class Tool{
private String name;
private String matchUrl;
public Tool(){
//empty ctor
}
public String getName(){
return name;
}
public void setName(String name){
this.name= name;
}
public String getMatchUrl(){
return matchUrl;
}
public void setMatchUrl(String matchUrl){
this.matchUrl= matchUrl;
}
@Override
public String toString(){
StringBuffer sb = new StringBuffer();
String ls = System.lineSeparator();
sb.append(ls);
sb.append("name: " + name);
sb.append(ls);
sb.append("matchUrl: " + matchUrl);
sb.append(ls);
}
}
@Autowiredを介して別のクラスでこの組み合わせを使用しました
@Component
public class SomeOtherClass{
private Logger logger = LoggerFactory.getLogger(SomeOtherClass.class);
@Autowired
private Tools tools;
/* excluded non-related code */
@PostConstruct
private void init(){
List<Tool> toolList = tools.getToolList();
if(toolList.size() > 0){
for(Tool t: toolList){
logger.info(t.toString());
}
}else{
logger.info("*****----- tool size is zero -----*****");
}
}
/* excluded non-related code */
}
そして、私のログには、名前と一致するURLが記録されました。これは別のマシンで開発されたため、上記のすべてを再入力する必要があったので、誤ってタイプミスした場合は事前にご容赦ください。
この統合コメントが多くの人に役立つことを願っています。このスレッドへの以前の貢献者に感謝します!
私もこれに関して多くの問題を抱えていました。私は最終的に何が最終的な取引であるかを見つけました。
@Gokhan Onerの回答を参照すると、サービスクラスとオブジェクトを表すPOJO、YAML設定ファイルを取得したら、アノテーション@ConfigurationPropertiesを使用する場合は、使用できるようにオブジェクトを明示的に取得する必要がありますそれ。好む :
@ConfigurationProperties(prefix = "available-payment-channels-list")
//@Configuration <- you don't specificly need this, instead you're doing something else
public class AvailableChannelsConfiguration {
private String xyz;
//initialize arraylist
private List<ChannelConfiguration> channelConfigurations = new ArrayList<>();
public AvailableChannelsConfiguration() {
for(ChannelConfiguration current : this.getChannelConfigurations()) {
System.out.println(current.getName()); //TADAAA
}
}
public List<ChannelConfiguration> getChannelConfigurations() {
return this.channelConfigurations;
}
public static class ChannelConfiguration {
private String name;
private String companyBankAccount;
}
}
そして、ここに行きます。地獄のように単純ですが、オブジェクトゲッターを呼び出す必要があることを知っておく必要があります。私は初期化を待っていました。オブジェクトが値で構築されていて、そうではないことを望んでいました。それが役に立てば幸い :)
私にとって修正は、@ ConfigurationProperitesアノテーションが付けられたクラスの内部クラスとして、挿入されたクラスを追加することでした。プロパティを挿入するには@Componentが必要だからです。