问题描述
在读取 yaml 时如果丢失了一个密钥如何验证? 读取yaml的API是snakeYaml
Yaml yaml = new Yaml(new Constructor(config.class));
InputStream in = Files.newInputStream(filepath);
yaml.load(in);
预期的 YAML:
KEY1:
innerKey1:
innerKey2: value1
innerKey3: value2
innerKey4:value3
在读取 yaml 时如果丢失了一个键如何抛出错误? 读取 yaml 时的示例,如果 innerKey3 被遗漏,如何在不迭代所有键的情况下验证它,因为我们已经为该 yaml 定义了一个 POJO。
输入 yaml:
KEY1:
innerKey1:
innerKey2: value1
innerKey4:value3
预期: 缺少innerKey3
解决方法
默认情况下,load() 方法返回一个 Map 实例,所以如果你提前知道键名,但是遍历嵌套属性并不容易。所以在 yaml.load(in)
之后你可以添加一个断言来检查。
assertTrue(document.containsKey("key_you_know"));
但如果是嵌套对象,则应该定义一些自定义类。
class Key {
private List<InnerKey> innerKeys; // innerKey1
private String value4; // equal to your innerKey4
// getters and setters
}
class InnerKey {
private String value2; // innerKey2
private String value3; // innerKey3
// getters and setters
}
然后做断言
Key key = yaml.load(in);
assertNotNull(key.getValue3());
,
其中一种方法可能是将 YAML 转换为 JSON,然后使用 json 模式验证器来验证该 json。有多个库可以将 yaml 转换为 JSON 请检查此线程以将 yaml 转换为 JSON。 How do I convert from YAML to JSON in Java?
获得 JSON 后,您可以使用任何 json 模式验证器,例如 Networklint/Everit。
,您需要定义一个 TypeDescription
来实现检查所有字段是否存在的附加逻辑:
public class FieldChecker extends TypeDescription {
public FieldChecker(Class<? extends Object> cls) {
super(cls);
}
/** This is called during construction for creating a new instance
of our class. The fields are filled later but we can check here
whether all fields are there. */
@Override
public Object newInstance(Node node) {
/** our objects will always be constructed from mapping nodes. */
final MappingNode m = (MappingNode)node;
/** TypeDescription implements the logic discovering the
class properties via getProperties() */
for (Property p : getProperties()) {
boolean found = false;
// search for a key with matching name in the mapping
for (NodeTuple p : m.getValue()) {
// assume all mapping keys are scalars
if (((ScalarNode)p.getKeyNode()).getValue().equals(p.getName())) {
found = true;
break;
}
}
if (!found) {
throw new ConstructorException(null,null,"missing key: " + p.getName(),node.getStartMark(),null);
}
}
// the fields are filled later by SnakeYAML.
return getType().newInstance();
}
}
现在,您需要对输入中要检查字段的每个类使用它:
Yaml yaml = new Yaml(new Constructor(new FieldChecker(config.class),List.of(
new FieldChecker(other.class),new FieldChecker(another.class),...)));