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 对象加载。