简体   繁体   English

如何使用 Java/Jackson 解析 YAML 文件并管理 $ref 参考值

[英]How to parse a YAML file with Java/Jackson and manage $ref reference values

I am parsing a YAML file that contains $ref properties using Jackson in Java:我正在使用 Java 中的 Jackson 解析包含 $ref 属性的 YAML 文件:

servers:
  server1:
    name: EU server
    host:
      $ref: '#/definitions/host'
  server2:
    name: USA server
    host:
      $ref: '#/definitions/host'

definitions:
  host:
    ip: 10.0.0.1
    port: 9999

Code:代码:

    String content = ...;

    ObjectMapper objectMapper = new ObjectMapper(new YAMLFactory());
    objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

    Servers servers = objectMapper.readValue(content, Servers.class);

How can I configure Jackson to follow the $ref properties?如何配置 Jackson 以遵循 $ref 属性?

Edit: The resulting object would have servers.server1.host.ip and servers.server1.host.port properties available instead of the $ref property.编辑:生成的 object 将具有可用的 servers.server1.host.ip 和 servers.server1.host.port 属性,而不是 $ref 属性。

$ref in YAML is just a scalar, it does not have any special meaning. YAML 中的$ref只是一个标量,没有任何特殊含义。 You are probably using a tool that assigns a special meaning to it, but you don't tell us which one.您可能正在使用一种为其赋予特殊含义的工具,但您没有告诉我们是哪一个。

Jackson is able to load YAML, but does not have builtin support for application-specific schemas (a schema in YAML is what assigns special properties to a scalar like $ref ). Jackson 能够加载 YAML,但没有对特定于应用程序的模式的内置支持(YAML 中的模式将特殊属性分配给像$ref之类的标量)。 This means that if you want to interpret $ref according to the semantics of whatever tool you're using, you need to implement it yourself or use the API of that tool if possible.这意味着如果您想根据您使用的任何工具的语义来解释$ref ,您需要自己实现它或尽可能使用该工具的 API。

If you assumed that $ref is a YAML feature (it is not), have a look at anchors and aliases which are the YAML way of referencing a previously defined node:如果您假设$ref是 YAML 功能(它不是),请查看锚点和别名,它们是 YAML 引用先前定义的节点的方式:

foo: &bar original  # scalar `original` with anchor
bar: *bar           # reference to scalar `original`

You may couple SnakeYAML and Jackson.你可以耦合 SnakeYAML 和 Jackson。 SnakeYAML is embedded in Jackson (and is used internally by it), so you already have access to it. SnakeYAML 嵌入在 Jackson 中(并在其内部使用),因此您已经可以访问它。

Convert first the YAML string to Map (the aliases are resolved):首先将 YAML 字符串转换为 Map(别名已解析):

import org.yaml.snakeyaml.Yaml;

Yaml yaml = new Yaml();
Map<String, Object> obj = yaml.load(<yamlStr>);

Then, use Jackson to serialize it to your model:然后,使用 Jackson 将其序列化为您的 model:

ObjectMapper mapper = new ObjectMapper();
MyModel model = mapper.convertValue(obj, MyModel.class);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM