2015-09-15 3 views
28

In meiner Spring Boot App habe ich application.yaml Konfigurationsdatei mit folgendem Inhalt. Ich möchte es als Configuration-Objekt injiziert haben, mit Liste der Kanalkonfigurationen:Mapping-Liste in Yaml zur Liste der Objekte in Spring Boot

available-payment-channels-list: 
    xyz: "123" 
    channelConfigurations: 
    - 
     name: "Company X" 
     companyBankAccount: "1000200030004000" 
    - 
     name: "Company Y" 
     companyBankAccount: "1000200030004000" 

Und @Configuration Objekt, das ich mit der Liste PaymentConfiguration Objekten gefüllt werden soll:

@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 
     } 

    } 

Ich bin Injektion dies als eine normale Bean mit @ Autowired-Konstruktor. Wert von xyz ist korrekt aufgefüllt, aber wenn der Frühling versucht YAML in der Liste der Objekte zu analysieren Ich erhalte

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] 

Irgendwelche Hinweise, was hier falsch ist?

+0

Ich habe genau das gleiche Problem: Ich habe eine Menge Dinge ausprobiert, aber ich habe ein leeres Objekt, oder entweder den gleichen Fehler 'Kann Wert des Typs ... String konvertieren .... zu MyObject ... keine passenden Editoren oder Konversionsstrategie gefunden ". Sonderbare Sache ist, dass ich nichts in Spring Boot geändert habe, das SnakeYAML Parameter oder Verhalten beeinflussen könnte ... Wirklich, was zum Teufel? – Alex

+0

Ich hätte fast vergessen, ich benutze Spring Boot 1.2.6 – Alex

Antwort

9

Der Grund woanders sein muss. Verwenden Sie nur Spring Boot 1.2.2 aus der Box ohne Konfiguration, es Just Works. Sehen Sie sich dieses Repo an - können Sie es kaputt machen?

https://github.com/konrad-garus/so-yaml

Sind Sie sicher, dass die YAML Datei eingefügt genau so aussieht? Keine zusätzlichen Leerzeichen, Zeichen, Sonderzeichen, falsche Einrückung oder etwas ähnliches? Ist es möglich, dass Sie eine andere Datei an anderer Stelle im Suchpfad haben, die statt der erwarteten verwendet wird?

+0

Ich tat das gleiche und für saubere SpringBoot Projekt funktioniert es. Es stellte sich heraus, dass sich unsere Anpassung des Ladens von Eigenschaften für verschiedene Umgebungen nicht ordnungsgemäß verlief. –

11
  • Sie brauchen nicht Konstrukteuren
  • Sie brauchen keine innere Klassen
  • RefreshScope haben einige Probleme mit Anmerkungen zu versehen, wenn sie mit @Configuration verwenden. Bitte sehen this github issue
Ihre Klasse ändern

wie folgt aus:

@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 
} 

} 
+0

Das gleiche Zeug, in der Regel ist Ihr Code nur eine Vereinfachung von mir verschachtelte Ausnahme ist java.lang.IllegalStateException: Kann Wert des Typs [java.lang.String] nicht konvertieren zum erforderlichen Typ [io.example.available_channels.AvailableChannelsConfiguration $ ChannelConfiguration] für die Eigenschaft 'channelConfigurations [0]': keine übereinstimmenden Editoren oder Konvertierungsstrategie gefunden] –

+0

Ich habe den Code ausgeführt und alle zugewiesenen Werte angezeigt. Haben Sie die RefreshScope-Annotation entfernt? –

+0

Und was ist Ihre Spring-Boot-Version? –

4

Ich hatte auch viel Probleme mit diesem. Ich habe endlich herausgefunden, was das letzte Geschäft ist.

Mit Bezug auf @ Gokhan Oner Antwort, sobald Sie Ihre Service-Klasse und das POJO für Ihr Objekt haben, Ihre YAML-Konfigurationsdatei schön und schlank, wenn Sie die Annotation @ConfigurationProperties verwenden, müssen Sie das Objekt explizit abrufen in der Lage sein, es zu benutzen. Wie:

@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; 
    } 

} 

Und dann los gehts. Es ist einfach, aber wir müssen wissen, dass wir den Objekt-Getter nennen müssen. Ich habe bei der Initialisierung gewartet und wünschte, das Objekt würde mit dem Wert gebaut, aber nein. Hoffe es hilft :)

3

Ich hatte diesen Artikel und viele andere referenziert und fand keine eindeutige prägnante Antwort zu helfen. Ich biete meine Entdeckung, kam zu einigen Referenzen aus diesem Thread in der folgenden:

Frühlings-Boot-Version: 1.3.5.RELEASE

Frühlings-Core-Version: 4.2.6.RELEASE

Abhängigkeitsverwaltung: Brixton.SR1

Das Folgende ist die einschlägige yaml Auszug:

tools: 
    toolList: 
    - 
     name: jira 
     matchUrl: http://someJiraUrl 
    - 
     name: bamboo 
     matchUrl: http://someBambooUrl 

Ich habe eine 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; 
    } 
} 

I eine Tool.class erstellt:

@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); 
    } 
} 

I verwendet Diese Kombination in einer anderen Klasse durch @ 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 */ 

} 

Und in meinen Protokollen wurden der Name und die übereinstimmenden URLs protokolliert. Dies wurde auf einer anderen Maschine entwickelt und daher musste ich alle oben genannten Punkte erneut eingeben. Bitte vergib mir im Voraus, wenn ich mich versehentlich vertippt habe.

Ich hoffe, diese Konsolidierung Kommentar ist hilfreich für viele und ich danke den früheren Mitwirkenden zu diesem Thema!

+0

Sie benötigen keine '' Component'' Annotation für die Tool-Klasse – heroin

Verwandte Themen