【问题标题】:Parsing dynamic yaml and mapping them using annotations to java objects解析动态 yaml 并使用注解将它们映射到 java 对象
【发布时间】:2021-04-27 10:42:36
【问题描述】:

我想解析具有动态属性的 yaml 文件。所以,我有不同国家的 yaml 文件 - 荷兰.yml, usa.yml, uk.yml....等等

文件的内容将如下所示-

netherlands:
  name: netherlands
  type: country
  location:
    latitude: aaa
    longitude: bbb
  amsterdam:
    name: amsterdam
    type: city
    latitude: xxx
    longitude: yyy
  rotterdam:
    name: rotterdam
    type: city
    latitude: ddd
    longitude: ggg 
  hague:
    name: hague
    type: city
    latitude: kkk
    longitude: lll

我想在我的代码中解析并以这种方式阅读它 -

@country(name="netherlands")
Country country;

country.getAmsterdam.getLatitude()

我正在使用 Springboot 和 Java 11。 如何使用注释来实现这一点?我相信我需要为每个国家/地区编写自定义注释。但主要问题是每个国家/地区的城市名称都是动态的,城市的数量也会因国家/地区而异。此外,可以稍后在 yaml 中添加城市。 我能够编写代码来解析 yaml 并将其映射到我的对象。但是到目前为止我看到的是,它需要映射到具有固定属性的类,这不是我的情况。这是我写的代码,但它不符合我的目的。

ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
File file = new File(classLoader.getResource("netherlands.yml").getFile());
ObjectMapper om = new ObjectMapper(new YAMLFactory());
Country country = om.readValue(file, Country.class);

    public class Country{    
    private String name ;
    private String type;
    private Location location;    
    // Here I need the dynamic attributes for my cities

   }

我查看了很多文章,但找不到任何类似的例子。您能否建议一种方法来实现这一目标?非常感谢您的帮助。

【问题讨论】:

    标签: java spring-boot annotations yaml


    【解决方案1】:

    如果你的 .yml 文件不会在运行时改变,你可以考虑使用@ConfigurationPropertiesSpring 注解。

    使用它你可以像这样创建@Configuration 类:

    @Configuration
    @Data
    public class CountryConfiguration {
    
        @Bean
        @ConfigurationProperties(prefix = "netherlands")
        private final Country netherlands;
        
        ...
    }
    

    您还需要使用此answer 中描述的额外配置支持,以允许您的netherlands.yml 和其他人对@ConfigurationProperties 注释可见。

    关于动态字段的生成——这是不可能的,因为 Java 是一种静态类型语言。而且它没有任何意义,因为如果您不知道城市名称,您将无法与城市合作。因此,我建议您将 .yml 文件的结构更改为:

     netherlands:
      name: netherlands
      type: country
      location:
        latitude: aaa
        longitude: bbb
      cities:
        - amsterdam:
          ....
    

    如果不可能。什么时候可以考虑使用private final Map<String, Object> netherlands。

    【讨论】:

    • 感谢您的意见。我不想将城市作为列表,因为在迭代时您需要指定索引,而我希望它在您对国家名称使用点运算符时作为下拉列表出现。这也将解决您的观点,即如何处理不知道可用城市的人。它应该是一个下拉菜单,因此您可以使用 getter 和 setter,就像这样 - netherlands.getAmsterdam.setLattitude("1234"); 我喜欢 Map 选项。您能否提供一个代码示例如何实现这一点 - netherlands.getAmsterdam.setLattitude("1234");
    • 正如我所说,由于语言限制,这种方式是不可能的。当前模式的最佳动态选项是 Map 荷兰,其中您将拥有像“amsterdam”这样的键。
    猜你喜欢
    • 1970-01-01
    • 2015-10-25
    • 2021-12-27
    • 1970-01-01
    • 2018-03-26
    • 2017-01-17
    • 1970-01-01
    • 1970-01-01
    • 2016-11-15
    相关资源
    最近更新 更多