2015-12-03 3 views
14

I yml einen folgendes habe Escaping config:einen Punkt in einem Kartenschlüssel in Yaml im Frühjahr Boot-

foo: 
    bar.com: 
    a: b 
    baz.com: 
    a: c 

Mit folgenden Klasse Frühling versucht Karte mit den Tasten ‚Bar‘ und ‚baz‘, die Behandlung von Punkten zu injizieren als Trennzeichen:

public class JavaBean { 
    private Map<String, AnotherBean> foo; 
(...) 
} 

ich habe versucht, den Schlüssel zu zitieren (dh ‚bar.com‘ oder „bar.com“), aber ohne Erfolg - noch das gleiche Problem. Gibt es einen Weg dahin?

+1

Der Grund, warum der Schlüssel nicht hilft, ist, weil 'bar.com:', '" bar.com ":' und ''bar.com':' (und '? Bar.com') alle die darstellen genau dasselbe in YAML und alle werden zu der Zeichenkette 'bar.com' deserialisiert. Der Punkt bedeutet in YAML nichts Spezielles - das Verhalten, das Sie sehen, findet im Frühling statt, nachdem das YAML deserialisiert wurde. –

+0

Also ist Spring mit YamlPropertiesFactoryBean hinter den Kulissen? Wenn ja, gibt es eine Möglichkeit, stattdessen YamlMapFactoryBean zu verwenden? :) – theadam

Antwort

22

Eine leichte Überarbeitung @ fivetenwill Antwort, die auf Frühling Stiefel 1.4.3.RELEASE funktioniert für mich:

foo: 
    "[bar.com]": 
    a: b 
    "[baz.com]": 
    a: c 

Sie müssen die Klammern in Anführungszeichen setzen, sonst verwerfen die YAML-Parser im Grunde s sie, bevor sie zu Spring kommen, und sie machen es nicht in den Namen der Eigenschaft.

+0

Große Antwort. Klammern in Anführungszeichen funktionierten! –

+3

Dies sollte die akzeptierte Antwort sein! –

+0

Das funktionierte auch für mich – Rites

3

Dies ist nicht möglich, wenn Sie eine automatische Zuordnung von Yaml-Schlüsseln zu Java-Bean-Attributen wünschen. Grund ist, Spring zuerst konvertieren YAML in Eigenschaften-Format. Siehe Abschnitt 24.6.1 der unten stehenden Link:

https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html

So, Ihr YAML umgewandelt wird:

foo.bar.com.a=b 
foo.baz.com.a=c 

Above Schlüssel werden als Standardeigenschaften analysiert.

Als eine Arbeit können Sie Spring YamlMapFactoryBean verwenden, um eine Yaml Map zu erstellen, wie es ist. Dann können Sie diese Karte verwenden, um eigene Java-Beans zu erstellen.

@Configuration 
public class Config { 

    private Map<String, Object> foo; 

    @Bean 
    public Map<String, Object> setup() { 
     foo = yamlFactory().getObject(); 
     System.out.println(foo); //Prints {foo={bar.com={a=b}, baz.com={a=c}}} 
     return foo; 
    } 

    @Bean 
    public YamlMapFactoryBean yamlFactory() { 
     YamlMapFactoryBean factory = new YamlMapFactoryBean(); 
     factory.setResources(resource()); 
     return factory; 
    } 

    public Resource resource() { 
     return new ClassPathResource("a.yaml"); //a.yaml contains your yaml config in question 
    } 

} 
+0

Irgendeine Möglichkeit, die YamlMapFactoryBean eine Karte von bestimmten Bean-Instanzen anstelle von Karte von Karten zurückgeben? Gibt es eine Möglichkeit, eine Karte von einem bestimmten Konfigurationsknoten zurückzugeben? Mein Yml ist komplizierter, die Map-Konfiguration ist nur ein Teil davon und ich würde lieber nicht nur die Map-Konfiguration in eine separate Konfiguration trennen. Der obige Code ist hackish genug für mich :) – theadam

+0

Ich stimme dir zu. Der obige Code ist ein bisschen herumzuarbeiten. Aber um das Maximum aus der Auto-Konfiguration herauszuholen, fürchte ich, dass Sie Punkte in Ihren Yaml-Tasten aufgeben müssen. Andernfalls können Sie in der obigen setup() - Methode das yaml-Objekt iterieren und manuell Beans erstellen (dies kann zu Problemen bei der automatischen Verdrahtung führen). – Mohit

+0

Ja, ich verstehe. Ich werde immer noch versuchen zu sehen, wie Spring dies autradiert und vielleicht gibt es eine Möglichkeit, es von Karte statt von Eigenschaften zu autowire :) – theadam

Verwandte Themen