转义Spring Boot中Yaml中映射键中的一个点

转义Spring Boot中Yaml中映射键中的一个点,spring,spring-boot,key,yaml,Spring,Spring Boot,Key,Yaml,我有以下yml配置: foo: bar.com: a: b baz.com: a: c 在下面的类中,Spring尝试使用键“bar”和“baz”注入map,将点视为分隔符: public class JavaBean { private Map<String, AnotherBean> foo; (...) } 公共类JavaBean{ 私人地图馆; (...) } 我试着引用密钥(即“bar.com”或“bar.com”),但没有用——仍然是

我有以下yml配置:

foo:
  bar.com:
    a: b
  baz.com:
    a: c
在下面的类中,Spring尝试使用键“bar”和“baz”注入map,将点视为分隔符:

public class JavaBean {
    private Map<String, AnotherBean> foo;
(...)
}
公共类JavaBean{
私人地图馆;
(...)
}

我试着引用密钥(即“bar.com”或“bar.com”),但没有用——仍然是同样的问题。有办法解决这个问题吗?

如果您想将yaml键自动映射到JavaBean属性,这是不可能的。原因是,Spring首先将YAML转换为属性格式。 见下文链接第24.6.1节:

因此,您的YAML将转换为:

foo.bar.com.a=b
foo.baz.com.a=c
以上键被解析为标准属性

作为一种解决方法,您可以使用Spring的
YamlMapFactoryBean
按原样创建Yaml映射。然后,您可以使用该映射自己创建JavaBean

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

}
@配置
公共类配置{
私人地图馆;
@豆子
公共地图设置(){
foo=yamlFactory().getObject();
System.out.println(foo);//打印{foo={bar.com={a=b},baz.com={a=c}}
返回foo;
}
@豆子
公共YamlMapFactoryBean yamlFactory(){
YamlMapFactoryBean工厂=新的YamlMapFactoryBean();
setResources(resource());
返回工厂;
}
公共资源{
返回新的ClassPathResource(“a.yaml”);//a.yaml包含有问题的yaml配置
}
}
这应该可以:

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

灵感来源于Wiki

对@fivetenwill的答案稍作修改,该答案在Spring Boot 1.4.3.RELEASE上适用于我:

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

您需要将括号括在引号内,否则YAML解析器基本上会在它们到达Spring之前丢弃它们,并且它们不会进入属性名。

引用键没有帮助的原因是因为
bar.com:
“bar.com”:
bar.com:
(和
?bar.com
)它们在YAML中表示完全相同的内容,并且都反序列化为字符串
bar.com
。点并不表示YAML中有任何特殊的行为。您看到的行为是在反序列化YAML后在Spring中发生的。Spring在幕后使用YamlPropertiesFactoryBean也是这样吗?如果是这样,有没有办法让它改用YamlMapFactoryBean有没有办法让YamlMapFactoryBean返回特定Bean实例的映射而不是映射的映射?有没有从特定配置节点返回映射的方法?我的yml更复杂,映射配置只是其中的一部分,我不想把映射配置和单独的配置分开。上面的代码对我来说已经够黑了:)我同意你的看法。上面的代码是一些需要解决的问题。但是为了获得最大限度的spring自动配置,我担心您将不得不放弃yaml键中的点。否则,在上面的setup()方法中,您可以迭代yaml对象并手动创建bean(这可能会导致自动连接问题)。尽管如此,我还是会尝试查找Spring是如何自动连接的,也许有一种方法可以使它从map而不是从properties自动连接:)@shivakumar,这种方法在Spring Boot 2.1.7.RELEASE中对我仍然有效。除了查看文档之外,不确定要向您提出什么建议,因为在SpringBoot2中有些规则有所更改。另见: