【问题标题】:SpringBoot map yaml to map of mapSpring Boot 将 yaml 映射到 map 的映射
【发布时间】:2019-07-08 04:36:41
【问题描述】:

是否可以将下面的 yaml 文件作为 Map<String, Map<String, String> 注入 Spring Boot 应用程序,其中 tradeType 将是外部映射的键,P 和 B 将是内部映射的键值。

tradeType:
    P: B
    S: S
securityCode: 
    ICI: ICICI Bank
    BOB: Bank of Baroda
    BOA: Bank of America
    BOS: Bank of Singapore 

正如建议的那样,这就是我的班级的样子。

@Configuration
@PropertySource("file:data/referenceDataMapping.yaml")
@ConfigurationProperties(prefix = "map")
public class ReferenceDataMapping {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    private Map<String, Map<String, String>> entries;

    @Override
    public String toString() {
        if (entries != null) {
            logger.info(entries.toString());
            return entries.toString();
        } else {
            return null;
        }
    }

    public Map<String, Map<String, String>> getEntries() {
        return entries;
    }

    public void setEntries(Map<String, Map<String, String>> entries) {
        this.entries = entries;
    }

}

来自 build.gradle

dependencies {
    compile 'org.springframework.boot:spring-boot-starter-activemq:2.1.2.RELEASE'
    compile 'org.springframework.boot:spring-boot-starter-security:2.1.2.RELEASE'
    compile 'org.springframework.boot:spring-boot-starter-web:2.1.2.RELEASE'
    compile 'org.apache.camel:camel-spring-boot-starter:2.23.1'
    compile 'org.apache.camel:camel-quartz2:2.23.1'
    compile 'org.apache.camel:camel-jms:2.23.1'
    compile 'org.apache.camel:camel-jacksonxml:2.23.1'
    compile 'com.fasterxml.jackson.core:jackson-databind:2.9.8'
    compile 'net.sf.saxon:Saxon-HE:9.9.1-1'
    testCompile 'org.springframework.boot:spring-boot-starter-test:2.1.2.RELEASE'
    testCompile 'org.springframework.security:spring-security-test:5.1.3.RELEASE'
}

referenceDataMapping.yaml

    map: 
   entries:
      tradeType:
          P: B
          S: S
      securityCode: 
          ICI: ICICI Bank
          BOB: Bank of Baroda
          BOA: Bank of America
          BOS: Bank of Singapore

【问题讨论】:

    标签: spring spring-boot yaml


    【解决方案1】:

    是的。这是可能的。

    @Configuration
    @ConfigurationProperties(prefix="map")
    public class Test {
    
        private Map<String,Map<String,String>> entires;
    
        public Map<String, Map<String, String>> getEntires() {
            return entires;
        }
    
        public void setEntires(Map<String, Map<String, String>> entires) {
            this.entires = entires;
        }
    
    }
    

    application.yml

    map:
      entires:
        tradeType:
          P: B
          S: S
        securityCode: 
          ICI: ICICI Bank
          BOB: Bank of Baroda
          BOA: Bank of America
          BOS: Bank of Singapore 
    

    输出:

    {tradeType={P=B, S=S}, securityCode={ICI=ICICI Bank, BOB=Bank of Baroda, BOA=Bank of America, BOS=Bank of Singapore}}
    

    更新:

    github-issue 中所述。 @PropertySource 不支持 yaml 文件。在这种情况下,请遵循本指南PropertySource-with-yaml-files

    【讨论】:

    • 谢谢巴拉特!我按照您的建议进行了尝试,但即使在应用程序启动后我的地图也是空的。我需要在我的 gradle 中包含任何依赖项吗?
    • 分享这个文件referenceDataMapping.yaml的条目
    • 配置属性只有在应用程序 ymls 中才会起作用。
    • 哦对了。正如我在这里看到的,issue 它不支持 .yaml 扩展名。但我可以看到它在 .properties 的情况下运行良好,如此处所述stack-47042237
    • 这对我不起作用,我尝试与 Barath 建议的完全相同。请参考带有代码、yaml 和 gradle 的原帖
    【解决方案2】:

    如果 YAML 与 application.yml 位于不同的文件中,

    @Component
    public class YourClass {
    
    
        private Map<String, String> tradeType;
        private Map<String, String> securityCode;
    
        public Map<String, String> getTradeType() {
            return tradeType;
        }
    
        public Map<String, String> getSecurityCode() {
            return securityCode;
        }
    
    
        @PostConstruct
        public void yamlFactory() {
            YamlMapFactoryBean factory = new YamlMapFactoryBean();
            factory.setResources(new ClassPathResource("your.yml"));
            tradeType = (Map<String, String>) factory.getObject().get("tradeType");
            securityCode = (Map<String, String>) factory.getObject().get("securityCode");
        }
    }
    

    【讨论】:

    • 如果这就是你要找的东西,请告诉我... 1 年前我遇到了很多困难才能做到这一点 :)
    • 让我试试这种方式,我不想声明 tradeType 和 securityCode,我希望它按照 yaml 是动态的,这就是我选择 map 的原因。
    • 然后,将其包装在父键中(my-outer-map,内部带有地图)并将类型更改为 Map>
    • 这是我的 yaml 验证器,如果您想尝试:varkeys-rhel-jenkins.westus.cloudapp.azure.com:8090/editor
    • 这是我的 yamlFactory 版本,用于返回通用映射 @PostConstruct public void yamlFactory() { YamlMapFactoryBean factory = new YamlMapFactoryBean(); factory.setResources(new ClassPathResource("referenceDataMapping.yaml")); Map&lt;String, Object&gt; map = factory.getObject(); entries = map.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, e -&gt; (Map&lt;String, String&gt;) e.getValue())); logger.info("map : " + entries.get("tradeType").get("P")); } 谢谢!阿南德和巴拉特!
    猜你喜欢
    • 2017-02-17
    • 2016-07-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-18
    • 2015-12-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多