【问题标题】:What's the best way to load a yaml file to Map(not an environment configuration file) in spring boot web project?在 Spring Boot Web 项目中将 yaml 文件加载到 Map(不是环境配置文件)的最佳方法是什么?
【发布时间】:2017-08-22 21:35:29
【问题描述】:

在我的数据框架层,我想从src/main/resources 读取一个 yaml。 文件名为mapconfigure.yaml。它与业务数据相关联,而不仅仅是环境配置数据。

它的内容是这样的:

person1: 
  name: aaa
  addresses: 
    na: jiang
    sb: su
person2: 
  name: bbb
  addresses: 
    to: jiang
    bit: su

我想将此信息存储到 HashMap 中。

是不是要使用@ConfigurationProperties之类的spring注解? 具体如何实现?

另外,我不能更改文件名。这意味着我必须使用mapconfigure.yaml 作为文件名,而不是application.ymlapplication.properties

我的HashMap的结构如下:

HashMap<String, Setting>

@Data
public class Setting{
  private String name;
  private HashMap<String, String> addresses
}

我的预期的HashMap如下:

{person1={name=aaa, addresses={na=jiang, sb=su}}, person2={name=bbb, addresses={to=jiang, bit=su}}}

我不确定是否可以使用YamlMapFactoryBean 类来执行此操作。

YamlMapFactoryBean类中getObject方法的返回类型是Map&lt;String, Object&gt;,不是泛型类型,如Map&lt;String, T&gt;

Spring boot doc刚才说了

Spring Framework 提供了两个方便的类,可用于加载 YAML 文档。 YamlPropertiesFactoryBean 将 YAML 作为 Properties 加载,YamlMapFactoryBean 将 YAML 作为 Map 加载。

但是没有详细的例子。

更新

在 github 中,我创建了一个示例。 It's Here。 在此示例中,我想将 myconfig.yaml 加载到 theMapProperties 类中的 SamplePropertyLoadingTest 对象。 Spring Boot 版本是 1.5.1,所以我不能使用@ConfigurationPropertieslocation 属性。 如何做到这一点?

【问题讨论】:

  • @niamingjian,请使用下面的链接,这将帮助您了解如何外部化配置。 docs.spring.io/spring-boot/docs/current/reference/html/…
  • 您希望将此信息存储到 HashMap 中。你想把它作为一个键还是一个值。如果您希望它作为键,值是什么,如果您想将数据加载到 HashMap 值中,键是什么?
  • @Anthon 我添加了我预期的地图。
  • @niaomingjian 这就是你加载YAML时应该得到的,因为顶层是一个映射,所以不需要在任何地方存储它,只需加载它。
  • @Anthon 问题是如何加载它。我不知道。

标签: spring-boot yaml


【解决方案1】:

您确实可以使用 @ConfigurationProperties 实现这一点。

从 Spring Boot 1.5.x 开始(缺少 @ConfigurationProperies 位置属性):

new SpringApplicationBuilder(Application.class)
    .properties("spring.config.name=application,your-filename")
    .run(args);

@Component
@ConfigurationProperties
public class TheProperties {
    private Map<String, Person> people;
    // getters and setters are omitted for brevity
}

在 Spring Boot 1.3.x 中:

@Component
@ConfigurationProperties(locations = "classpath:your-filename.yml")
public class TheProperties {
    private Map<String, Person> people;
    // getters and setters are omitted for brevity
}

上述示例的 Person 类如下所示:

public class Person {
    private String name;
    private Map<String, String> addresses;
    // getters and setters are omitted for brevity
}

我已经使用以下文件测试了代码:your-filename.yml 在 src/main/resources 中定义,内容:

people:
  person1:
    name: "aaa"
    addresses:
      na: "jiang"
      sb: "su"
  person2:
    name: "bbb"
    addresses:
      to: "jiang"
      bit: "su"

如果您需要任何进一步的帮助,请告诉我。

【讨论】:

  • 有两个问题。首先,我使用的是springboot1.5.1,在这个版本中@ConfigurationPropertieslocations属性已被移动。其次,我的文件中没有people:元素。
  • 如果遇到第一个问题(spring boot 1.5.x 中缺少位置属性),您可以调整 spring.config.name 属性(github.com/spring-projects/spring-boot/issues/…)。关于第二个问题,您可以以任何方式修改 mapconfigure.yaml 吗?不能加个前缀比如:people(名字无关紧要,应该简单对应Java代码中的Map名称)?
  • 另一方面,如果 mapconfigure.yaml 中的数据是严格的业务数据,那么 ConfigurationProperties 可能不是最佳选择。在您提到的问题中 YamlMapFactoryBean。在stackoverflow.com/questions/34070987/… 接受的答案中,有一个 YamlMapFactoryBean 使用示例。
  • 非常感谢。我在 yaml 文件中添加了前缀 people 并在环境变量中添加了 spring.config.location 属性来定义我的自定义文件。如果我使用YamlMapFactoryBean,我会得到像Map&lt;String, T&gt; 这样的generic Map 吗?
  • 提到的解决方案也适用于 Spring Boot 2.0.x。
【解决方案2】:

试试这个

 YamlPropertySourceLoader loader = new YamlPropertySourceLoader();
        try {
            PropertySource<?> applicationYamlPropertySource = loader.load(
                "properties", new ClassPathResource("application.yml"), null);// null indicated common properties for all profiles.
            Map source = ((MapPropertySource) applicationYamlPropertySource).getSource();
            Properties properties = new Properties();
            properties.putAll(source);
            return properties;
        } catch (IOException e) {
            LOG.error("application.yml file cannot be found.");
        }

【讨论】:

  • 这是一个网络应用程序,所以我认为我不应该直接new它。我应该使用Dependency Injection 自动执行此操作。
  • 当然。这只是显示如何阅读的示例代码。 yaml 文件。更改它以满足您的需求和最佳实践
  • 这只是我的问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-08-07
  • 1970-01-01
  • 2019-09-08
  • 1970-01-01
  • 2023-03-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多