2 回答
TA贡献1804条经验 获得超3个赞
您得到的错误可能源于您显示的 YAML 与您显示的类不对应。someObjList在您的 YAML 数据中是一个映射(包含键值对,第一个键是obj1),而在您的类中,它是一个ArrayList<SomeObject>. 这对应于您的 YAML 数据中的一个序列,应该如下所示:
someObjList:
- objName: strname
strList:
- 100
- 200
- 300
- # (...)
但是,我不确定,因为您并没有真正显示产生错误的代码。
话虽如此,如果您正在寻找一种通过任意 YAML 进行搜索的方法,请不要使用 Jackson。Jackson 是一个(反)序列化的工具,你不想反序列化你的 YAML;你只想走它的结构。为此,您可以使用 SnakeYAML,它是 Jackson 使用的 YAML 解析器:
Yaml yaml = new Yaml();
Node root = yaml.compose(new StringReader("foo: bar"));
root将是 a ScalarNode、 aMappingNode或 a SequenceNode。后两个将包含您可以下降的子节点。这种结构对于类似 XPath 的搜索当然是可行的。
如果您追求性能,更快的方法是使用parseSnakeYaml 的顺序接口。基本上,您不断地从解析器中查询下一个事件并检查您正在搜索的路径是否包含它。如果是这样,继续查询它的子元素并在那里搜索路径中的下一个元素。如果没有,解析并转储当前事件的所有子内容,然后继续搜索当前路径元素。
如果您可以阅读 Python,您可以从我的回答中获得一些灵感,该回答通过事件解析输入 YAML,并且您可以指定要附加数据的路径。
TA贡献1895条经验 获得超7个赞
您会看到Cannot deserialize instance of "java.util.ArrayList" out of START_OBJECT token,因为在您定义的根级别ArrayList<SomeContainer> containers但YAML文件包含object. 为避免这种情况,我们需要配置ObjectMapper为接受单个对象,例如array:
ObjectMapper mapper = new ObjectMapper(new YAMLFactory());
mapper.enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY);
此外,obj1并且obj2未在您的模型中定义。所以你应该删除它们或创建额外的包装对象。但如果您只需要遍历YAML文件,您可以将其读取为Map. 下面的代码:
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
import java.io.File;
import java.util.Map;
public class YamlApp {
public static void main(String[] args) throws Exception {
File yamlFile = new File("./resource/test.yaml").getAbsoluteFile();
ObjectMapper mapper = new ObjectMapper(new YAMLFactory());
Map yaml = mapper.readValue(yamlFile, Map.class);
System.out.println(yaml);
}
}
印刷:
{container={name=Cont1, path=/storage/outputFolder, intList=[100, 200, 300], strList=[strFirst, strSecond, strThird], someObjList={obj1={objName=strname, strList=[100, 200, 300]}, obj2={objName=strname2, strList=[1002, 2002, 3002]}}}}
添加回答
举报