2015-12-03 7 views
14

Mam następujący yml config:Uciekając kropkę w kluczu Mapa w yaml wiosną Boot

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

Z następujące klasy Wiosna próbuje wstrzyknąć mapę z kluczami „Bar” i „Baz”, traktując kropek jako separatora:

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

próbowałem podając klucz (czyli „bar.com” lub „bar.com”), ale bezskutecznie - jeszcze tego samego problemu. Czy istnieje sposób obejścia tego?

+1

Powód cytowania klucza nie pomógł, ponieważ 'bar.com:', '" bar.com ":' i ''bar.com':' (i '? Bar.com') wszystkie reprezentują dokładnie to samo w YAML i wszystkie są deserializowane do ciągu 'bar.com'. Kropka nie oznacza nic specjalnego w YAML - obserwowane zachowanie ma miejsce wiosną po deserializacji YAML. –

+0

Więc czy SPring używa YamlPropertiesFactoryBean za kulisami? Jeśli tak, czy jest jakiś sposób, aby zamiast tego użyć YamlMapFactoryBean? :) – theadam

Odpowiedz

22

Nieznaczna zmiana użytkownika @ fivetenwill odpowiedź, która działa dla mnie na wiosenny Boot 1.4.3.RELEASE:

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

Potrzebujesz nawiasów w cudzysłowach, w przeciwnym razie parser YAML będzie w zasadzie odrzucany s je, zanim dotrą na wiosnę, i nie wchodzą do nazwy nieruchomości.

+0

Świetna odpowiedź. Nawiasy w cudzysłowach działały! –

+3

To powinna być zaakceptowana odpowiedź! –

+0

To zadziałało także dla mnie – Rites

3

Nie jest to możliwe, jeśli chcesz automatycznie mapować klucze yaml na atrybuty bean Java. Powód: najpierw Spring przekonwertuj YAML na format właściwości. Patrz rozdział 24.6.1 z linku poniżej:

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

Więc twój YAML jest konwertowany do:

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

klucze powyżej są analizowane jako właściwości standardowych.

Podczas pracy można użyć funkcji Spring's YamlMapFactoryBean, aby utworzyć mapę Yaml taką, jaka jest. Następnie możesz użyć tej mapy do samodzielnego tworzenia komponentów bean Java.

@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

Jakikolwiek sposób, aby YamlMapFactoryBean zwrócił mapę pewnych instancji Bean zamiast mapy map? Jakikolwiek sposób zwrócić mapę z określonego węzła konfiguracyjnego? Mój yml jest bardziej skomplikowany, konfiguracja mapy jest tylko jego częścią i wolałbym nie oddzielać tylko konfiguracji mapy, aby oddzielić konfigurację. Powyższy kod jest dla mnie wystarczająco hackowaty :) – theadam

+0

Zgadzam się z Tobą. Powyższy kod to trochę pracy. Ale aby uzyskać maksymalną automatyczną konfigurację wiosenną, obawiam się, że będziesz musiał zrezygnować z kropek w swoich klawiszach yaml. W przeciwnym razie, w metodzie setup() powyżej, możesz iterować obiekt yaml i tworzyć fasole ręcznie (może to powodować problemy z automatycznym okablowaniem). – Mohit

+0

Tak, rozumiem. Nadal spróbuję sprawdzić, jak Spring to autodestrukcyjnie i być może istnieje sposób, aby zrobić to autowirem z mapy zamiast z właściwości :) – theadam