【问题标题】:Reading a map from yaml in Java getting null从 Java 中的 yaml 读取地图变为空
【发布时间】:2016-04-14 08:23:44
【问题描述】:

我在使用 spring 通过 java 读取我的 yaml 时遇到问题。让我先显示代码

@Component
@EnableConfigurationProperties
@ConfigurationProperties(prefix = "countries")
public class UserLimitReader {

    private HashMap<String, Integer> orders;

    private HashMap<String, Integer> requests;

    public HashMap<String, Integer> getOrders() {
        return orders;
    }

    public void setOrderRedeemableLimit(HashMap<String, Integer>         orders) 
{
        this.orders= orders;
}

public HashMap<String, Integer> getRequests() {
    return requests;
}

public void setMonthlyRedeemableLimit(HashMap<String, Integer> requests) {
    this.requests= requests;
}
}

我的 yaml 文件:

cassandra:
    hosts: localhost:9142, 127.0.0.1:9142
    keyspace: test
countries:
    orders:
      JPY: 1000
      USD: 1000
    requests:
      JPY: 100000
      USD: 100000

spring上下文xml也有这个:

<bean id="yamlProperties"
    class="org.springframework.beans.factory.config.YamlPropertiesFactoryBean">
    <property name="resources">
        <value>classpath:config/application.yaml</value>
    </property>
</bean>

<context:property-placeholder
    properties-ref="yamlProperties" />

现在,我的期望是,在我的 spring-test 应用程序运行时(上下文 xml 来自我的测试资源,yaml 也在我的测试中),这些订单和请求的值已设置,但它们为空。另外,请注意,除了我使用 @Value(${...}) 注入的这些值之外,我的 yaml 中还有其他值,它们被注入绝对没问题!

我看了这个:Spring Boot - inject map from application.yml

我做了几乎相同的事情,但是我的价值观还没有设定。请帮忙。

我正在通过谷歌,找到这个链接: http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/beans/factory/config/YamlPropertiesFactoryBean.html

在这里,它说,所有内容都被读取为字符串而不是映射。有没有其他类支持读取 Yaml 文件,就像他们在这里所做的那样:Spring Boot - inject map from application.yml

还是我对 YamlPropertiesFactoryBean 的理解有误?

compile 'org.springframework:spring-core:4.2.+'
compile 'org.springframework:spring-beans:4.2.+'
compile 'org.springframework:spring-context:4.2.+'
compile 'org.springframework.boot:spring-boot:1.3.1.RELEASE'
compile 'org.springframework.boot:spring-boot-configuration-processor:1.3.1.RELEASE'

这些是 gradle 中的依赖项。你可能想知道为什么我有 spring-core 和 spring-boot,本质上,我不想要 spring-boot,但是没有 spring-boot,我不能添加 @EnableConfigurationProperties 和 @ConfigurationProperties,老实说我不知道我是否可以在没有它们的情况下将 yaml 内容读入地图。因此添加了这两个依赖项,但如果有办法删除它们,我会非常乐意删除这两个依赖项。

热烈的问候, 帕万

【问题讨论】:

  • 你确定你的类是由 spring 加载的吗?我在您的上下文文件中没有看到对 UserLimitReader 的任何引用。您是否正在使用您遗漏的组件扫描?
  • 嗨 Koby,这是加载它的 spring 的一部分:classpath:config/application.yaml 事实是我的其他bean,在这里,它正在加载!
  • 但是我不能对 UserLimitReader 做同样的事情,因为它总是抛出一个错误提示,无法解析 "${countries.orders}" 中提到的占位符 country.orders
  • 请查看我关于如何在 Spring 中读取 YAML 文件并将其包含在 JUnit 和 TestNG 测试中的评论:stackoverflow.com/a/37270778/3634283
  • @ayurchuk:这个问题更多的是直接将条目读取到地图中。但是您正在从 yaml 中读取数据,这有帮助,但在这种情况下可能不会。但这绝对有帮助,我猜 Koby 提供的解决方案帮助我解决了问题。

标签: java spring dictionary yaml


【解决方案1】:

我在使用不同的泛型类型时遇到了同样的问题,我通过初始化 map 成员并删除了 setter 方法来解决它,例如:

@Component
@EnableConfigurationProperties
@ConfigurationProperties(prefix = "countries")
public class UserLimitReader{
    private Map<String, Integer> orders = new HashMap<>();

    private Map<String, Integer> requests = new HashMap<>();

    public Map<String, Integer> getOrders() {
        return orders;
    }
    ...
}

请注意,我使用了 java 7 菱形运算符并将成员类型更改为 Map 而不是 HashMap。

重要提示:在我的代码中,我使用 Spring 的配置类而不是 XML,并将 EnableConfigurationProperties 移动到配置类。在你的情况下,它应该是这样的:

@Configuration
@EnableConfigurationProperties(value = {UserLimitReader.class})
public class SpringConfiguration {
    ...
}

@ConfigurationProperties(prefix = "countries", locations: "classpath:config/application.yaml")
public class UserLimitReader {
    ...
}

不知道你是如何使用 XML 配置它的,但是正如我在我的 cmets 中所写的,我仍然认为你应该确保 Spring 使用组件扫描或类似的方法找到你的类。

@Value 在 Spring 加载 YAML 文件时使用您的上下文文件没有任何问题,但这并不意味着 UserLimitReader 文件由 Spring 加载和配置。

【讨论】:

  • 嗨科比,非常感谢!我所做的是:@Component @EnableConfigurationProperties@ConfigurationProperties(prefix = PointServiceConstants.COUNTRY, locations = PointServiceConstants.CLASSPATH) public class UserLimitReader { private Map orderRedeemableLimit = new HashMap();私有 Map 每月可兑换限制 = 新 HashMap(); ... }
  • 这是唯一对我有用的解决方案...为什么通过未初始化的属性和 getter/setter 进行的简单自动映射不起作用?有人有解释吗? THX
猜你喜欢
  • 1970-01-01
  • 2014-12-05
  • 1970-01-01
  • 2015-04-22
  • 2016-11-19
  • 2013-08-18
  • 1970-01-01
相关资源
最近更新 更多