我如何以与使用@ configationproperties相同的方式以编程方式加载yaml文件

How do i load a yaml file programatically the same way as using @ConfiguationProperties?

本文关键字:方式 编程 加载 文件 yaml configationproperties      更新时间:2023-09-26

不确定这是否是个问题,或者我只是没有以正确的方式去做。我的问题是,我试图以2种方式加载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;
    }
}

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

测试提取配置的代码:

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转换为对象到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);
        }
    }

可能的解决方案不是最好的,但可以完成工作。我能够将YAML转换为对象到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);
    }
}

这个问题的解决方案是首先使用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);

现在使用这个map的map,您可以使用自定义逻辑轻松地将它映射到。properties文件。

你也可以在代码中使用这个映射来读取属性