yaml YAMLException:如何使用 SnakeYaml 配置?
yaml YAMLException: How to configure using SnakeYaml?
我正在尝试使用 SnakeYaml 库来使用 YAML 文件配置我的项目。
我已经读过这个例子:Here
我遵循该结构并且我有这些文件:
config/statisticsConfig.yml
:
statisticsTopologyParams:
tickTupleFrequency: 60
hourlyStatistics:
windowLength: 3600
emitFrequency: 60
dailyStatistics:
windowLength: 86400
emitFrequency: 3600
Configuration.java
:
public class Configuration {
Map<String, ServiceConfig> statisticsTopologyParams;
public Configuration() {
}
@Override
public String toString() {
return "YamlConfig{" +
"statistics=" + statisticsTopologyParams +
'}';
}
public Map<String, ServiceConfig> getStatisticsTopologyParams() {
return statisticsTopologyParams;
}
public void setStatisticsTopologyParams(Map<String, ServiceConfig> statisticsTopologyParams) {
this.statisticsTopologyParams = statisticsTopologyParams;
}
}
ServiceConfig.java
:
public class ServiceConfig {
private Integer tickTupleFrequency;
private Map<String, Integer> hourlyStatistics;
private Map<String, Integer> dailyStatistics;
public ServiceConfig() {
}
public Integer getTickTupleFrequency() {
return tickTupleFrequency;
}
public void setTickTupleFrequency(Integer tickTupleFrequency) {
this.tickTupleFrequency = tickTupleFrequency;
}
public Map<String, Integer> getHourlyStatistics() {
return hourlyStatistics;
}
public void setHourlyStatistics(Map<String, Integer> hourlyStatistics) {
this.hourlyStatistics = hourlyStatistics;
}
public Map<String, Integer> getDailyStatistics() {
return dailyStatistics;
}
public void setDailyStatistics(Map<String, Integer> dailyStatistics) {
this.dailyStatistics = dailyStatistics;
}
}
YamlConfigRunner.java
:
public class YamlConfigRunner {
public Configuration getConfiguration(String filePath) throws IOException {
Constructor constructor = new Constructor(Configuration.class);
Yaml yaml = new Yaml(constructor);
try (InputStream in = Files.newInputStream(Paths.get(filePath))) {
Configuration config = yaml.loadAs(in, Configuration.class);
System.out.println(config.toString());
return config;
}
}
}
但是我得到了异常:
null; Can't construct a java object for tag:yaml.org,2002:org.uniroma2.sdcc.Utils.Configuration; exception=Cannot create property=statisticsTopologyParams for JavaBean=YamlConfig{statistics=null}; No single argument constructor found for class org.uniroma2.sdcc.Utils.ServiceConfig; in 'reader', line 1, column 1:
statisticsTopologyParams:
Caused by: org.yaml.snakeyaml.error.YAMLException: No single argument constructor found for class org.uniroma2.sdcc.Utils.ServiceConfig
问题是您要告诉 SnakeYaml 将数字 (60
) 转换为 ServiceConfig
对象。由于 ServiceConfig
没有一个只接受一个参数的构造函数,SnakeYaml 不知道该怎么做。
更详细地说,这是失败的行:
tickTupleFrequency: 60
tickTupleFrequency
这里是一个Map<String, ServiceConfig>
的key。将它作为字符串加载是没有问题的,所以 SnakeYaml 就是这样做的。现在,有一个值 60
。这必须转换为 ServiceConfig
对象以适合地图。 SnakeYaml 应该如何做到这一点?它不知道,因此会产生错误。
您似乎只是忘记将地图级别添加到您的 YAML 中,因为 tickTupleFrequency
和以下键都是 ServiceConfig
对象的所有字段。所以也许这就是您真正想要的:
statisticsTopologyParams:
My fancy ServiceConfig:
tickTupleFrequency: 60
hourlyStatistics:
windowLength: 3600
emitFrequency: 60
dailyStatistics:
windowLength: 86400
emitFrequency: 3600
现在,My fancy ServiceConfig
将成为 Map<String, ServiceConfig>
中的键,包含的地图将作为 ServiceConfig
对象加载。
我正在尝试使用 SnakeYaml 库来使用 YAML 文件配置我的项目。 我已经读过这个例子:Here
我遵循该结构并且我有这些文件:
config/statisticsConfig.yml
:
statisticsTopologyParams:
tickTupleFrequency: 60
hourlyStatistics:
windowLength: 3600
emitFrequency: 60
dailyStatistics:
windowLength: 86400
emitFrequency: 3600
Configuration.java
:
public class Configuration {
Map<String, ServiceConfig> statisticsTopologyParams;
public Configuration() {
}
@Override
public String toString() {
return "YamlConfig{" +
"statistics=" + statisticsTopologyParams +
'}';
}
public Map<String, ServiceConfig> getStatisticsTopologyParams() {
return statisticsTopologyParams;
}
public void setStatisticsTopologyParams(Map<String, ServiceConfig> statisticsTopologyParams) {
this.statisticsTopologyParams = statisticsTopologyParams;
}
}
ServiceConfig.java
:
public class ServiceConfig {
private Integer tickTupleFrequency;
private Map<String, Integer> hourlyStatistics;
private Map<String, Integer> dailyStatistics;
public ServiceConfig() {
}
public Integer getTickTupleFrequency() {
return tickTupleFrequency;
}
public void setTickTupleFrequency(Integer tickTupleFrequency) {
this.tickTupleFrequency = tickTupleFrequency;
}
public Map<String, Integer> getHourlyStatistics() {
return hourlyStatistics;
}
public void setHourlyStatistics(Map<String, Integer> hourlyStatistics) {
this.hourlyStatistics = hourlyStatistics;
}
public Map<String, Integer> getDailyStatistics() {
return dailyStatistics;
}
public void setDailyStatistics(Map<String, Integer> dailyStatistics) {
this.dailyStatistics = dailyStatistics;
}
}
YamlConfigRunner.java
:
public class YamlConfigRunner {
public Configuration getConfiguration(String filePath) throws IOException {
Constructor constructor = new Constructor(Configuration.class);
Yaml yaml = new Yaml(constructor);
try (InputStream in = Files.newInputStream(Paths.get(filePath))) {
Configuration config = yaml.loadAs(in, Configuration.class);
System.out.println(config.toString());
return config;
}
}
}
但是我得到了异常:
null; Can't construct a java object for tag:yaml.org,2002:org.uniroma2.sdcc.Utils.Configuration; exception=Cannot create property=statisticsTopologyParams for JavaBean=YamlConfig{statistics=null}; No single argument constructor found for class org.uniroma2.sdcc.Utils.ServiceConfig; in 'reader', line 1, column 1:
statisticsTopologyParams:
Caused by: org.yaml.snakeyaml.error.YAMLException: No single argument constructor found for class org.uniroma2.sdcc.Utils.ServiceConfig
问题是您要告诉 SnakeYaml 将数字 (60
) 转换为 ServiceConfig
对象。由于 ServiceConfig
没有一个只接受一个参数的构造函数,SnakeYaml 不知道该怎么做。
更详细地说,这是失败的行:
tickTupleFrequency: 60
tickTupleFrequency
这里是一个Map<String, ServiceConfig>
的key。将它作为字符串加载是没有问题的,所以 SnakeYaml 就是这样做的。现在,有一个值 60
。这必须转换为 ServiceConfig
对象以适合地图。 SnakeYaml 应该如何做到这一点?它不知道,因此会产生错误。
您似乎只是忘记将地图级别添加到您的 YAML 中,因为 tickTupleFrequency
和以下键都是 ServiceConfig
对象的所有字段。所以也许这就是您真正想要的:
statisticsTopologyParams:
My fancy ServiceConfig:
tickTupleFrequency: 60
hourlyStatistics:
windowLength: 3600
emitFrequency: 60
dailyStatistics:
windowLength: 86400
emitFrequency: 3600
现在,My fancy ServiceConfig
将成为 Map<String, ServiceConfig>
中的键,包含的地图将作为 ServiceConfig
对象加载。