web-dev-qa-db-fra.com

Échapper un point dans une clé de carte dans Yaml dans Spring Boot

J'ai une configuration yml suivante:

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

Avec une classe suivante, Spring essaie d'injecter la carte avec les touches 'bar' et 'baz', en traitant les points comme séparateurs:

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

J'ai essayé de citer la clé (c'est-à-dire "bar.com" ou "bar.com") mais en vain - toujours le même problème. Y a-t-il un moyen de contourner ceci?

25
theadam

Une légère révision de la réponse de @ fivetenwill, qui fonctionne pour moi sur Spring Boot 1.4.3.

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

Vous devez placer les crochets entre guillemets, sinon l'analyseur YAML les supprime avant d'arriver à Spring, et ils n'entrent pas dans le nom de la propriété.

50
pioto

Cela n'est pas possible si vous souhaitez que le mappage automatique des clés yaml vers les attributs du bean Java. Raison étant, Spring convertit d'abord YAML au format des propriétés. Voir la section 24.6.1 du lien ci-dessous:

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

Ainsi, votre YAML est converti en:

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

Les clés ci-dessus sont analysées en tant que propriétés standard.

Pour contourner ce problème, vous pouvez utiliser YamlMapFactoryBean de Spring pour créer une carte Yaml telle quelle. Ensuite, vous pouvez utiliser cette carte pour créer vos propres beans 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
    }

}
4
Mohit

Cela devrait fonctionner:

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

Inspiré de Spring Boot Configuration Binding Wiki

1
fivetenwill