【问题标题】:How do i load a yaml file programatically the same way as using @ConfiguationProperties?如何以与使用 @ConfiguationProperties 相同的方式以编程方式加载 yaml 文件?
【发布时间】:2015-11-12 14:04:56
【问题描述】:

不确定这是否是一个问题,或者我只是没有以正确的方式进行。我的问题是我试图以两种方式加载 YAML 文件。一种方法是通过@configurationProperties 并指定一个位置。这很好用,并且 YAML 可以正确加载到我的 Java 对象中。

PageDescriptor.java

import java.util.HashMap;
import java.util.Map;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;

@Configuration
@ConfigurationProperties(locations = "classpath:config/page.yml")
public class PageDescriptor {
private HashMap pageConfigs;

public PageDescriptor() {

}

public HashMap<String, PageConfig> getPageConfigs() {
    return pageConfigs;
}

public void setPageConfigs(final HashMap<String, PageConfig> pageConfigs) {
    this.pageConfigs = pageConfigs;
}

PageConfig.java

public class PageConfig {
    private String baseUrl;
    private String configLocation;
    private String navDescriptorKey;
    private String defaultRoute;

    public PageConfig() {

    }

    public String getBaseUrl() {
        return baseUrl;
    }

    public void setBaseUrl(final String baseUrl) {
        this.baseUrl = baseUrl;
    }

    public String getDefaultRoute() {
        return defaultRoute;
    }

    public void setDefaultRoute(final String defaultRoute) {
        this.defaultRoute = defaultRoute;
    }

    public String getNavDescriptorKey() {
        return navDescriptorKey;
    }

    public void setNavDescriptorKey(final String navDescriptorKey) {
        this.navDescriptorKey = navDescriptorKey;
    }

    public String getConfigLocation() {
        return configLocation;
    }
}

接下来我试图通过 java 代码将其他 YAML 文件加载到同一个对象中。我是这样接近它的。

测试拉取配置的代码:

final PathMatchingResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver();
    final Resource[] resources = resourceResolver.getResources("classpath*:com/**/page.yml");
    if (!((resources == null) || (resources.length == 0))) {
        for (final Resource resource : resources) {
            // final Yaml yaml = new Yaml();
            // final InputStream in = resource.getInputStream();
            // final PageDescriptor componentPageDescriptor = yaml.loadAs(in, PageDescriptor.class);
            // in.close();
            final YamlConfigurationFactory<PageDescriptor> factory = new YamlConfigurationFactory<PageDescriptor>(
                    PageDescriptor.class);
            final Map<Class<?>, Map<String, String>> aliases = new HashMap<Class<?>, Map<String, String>>();
            // aliases.put(PageConfig.class, Collections.singletonMap("pageConfig", "pageConfig"));
            factory.setResource(resource);
            factory.setExceptionIfInvalid(true);
            factory.setPropertyAliases(aliases);
            // factory.setValidator(validator);
            factory.setMessageSource(new StaticMessageSource());
            factory.afterPropertiesSet();
            final PageDescriptor componentPageDescriptor = factory.getObject();
        }
    }

虽然这会将 componentPageDescriptor 对象作为 PageDescriptor 加载,但它不会正确加载 HashMap,而是会加载 HashMap>。有没有一种简单的方法来模拟 @ConfigurationProperties 在加载 YAML 文件时的工作方式?

下面是 YAML 文件

---
#pageDescriptors:
  pageConfigs:
    Home:
      baseUrl: ""
      configLocation: "/static/app/src/scripts/pages/home/config.js"
      navDescriptorKey: "Default"
      defaultRoute: ""

更新: 作为一个临时解决方案,我能够将 YAML 转换为 Object 转换为 JSON 转换为 PageDescriptor 并且它按预期工作。

    final PathMatchingResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver();
    final Resource[] resources = resourceResolver
            .getResources("classpath*:com/**/page.yml");

    if (!((resources == null) || (resources.length == 0))) {
        for (final Resource resource : resources) {
            final Yaml yaml = new Yaml();
            final Object map = yaml.load(resource.getInputStream());
            final ObjectWriter ow = new ObjectMapper().writer();
            final String componentPageDescriptorString = ow.writeValueAsString(map);
            final PageDescriptor componentPageDescriptor = new ObjectMapper()
                    .readValue(componentPageDescriptorString, PageDescriptor.class);
            pageDescriptor.merge(componentPageDescriptor);
        }
    }

【问题讨论】:

  • 您没有显示所有涉及的代码,并且您显示的代码包含语法错误。如果您提供minimal, complete, and verifiable example,人们会更容易为您提供帮助。
  • 我已经更新了问题中的代码,使其更加完整。如果您还有更多需要,请告诉我。

标签: javascript spring properties spring-boot yaml


【解决方案1】:

可能的解决方案不是最好的,但可以完成工作。我能够将 YAML 转换为 Object 转换为 JSON 转换为 PageDescriptor 并且它按预期工作。

final PathMatchingResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver();
final Resource[] resources = resourceResolver
        .getResources("classpath*:com/**/page.yml");

if (!((resources == null) || (resources.length == 0))) {
    for (final Resource resource : resources) {
        final Yaml yaml = new Yaml();
        final Object map = yaml.load(resource.getInputStream());
        final ObjectWriter ow = new ObjectMapper().writer();
        final String componentPageDescriptorString = ow.writeValueAsString(map);
        final PageDescriptor componentPageDescriptor = new ObjectMapper()
                .readValue(componentPageDescriptorString, PageDescriptor.class);
        pageDescriptor.merge(componentPageDescriptor);
    }
}

【讨论】:

    【解决方案2】:

    解决此问题的方法是先使用 objectMapper 将 YAML 转换为映射,然后将该映射转换为 .properties 文件。

    将其转换为地图

    Map<String, Object> configMap = new HashMap<String, Object>();
    
    File yamlFile = new File(yamlLocation);
    
    Yaml yaml = new Yaml();
    
    InputStream input = new FileInputStream(yamlFile);
    
    configMap = (Map<String, Object>) yaml.load(input);
    

    现在使用此地图地图,您可以使用自定义逻辑轻松地将其映射到 .properties 文件。

    您也可以在您的代码中使用此地图来读取属性。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-05-16
      • 2014-07-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-16
      • 2012-01-10
      • 1970-01-01
      相关资源
      最近更新 更多