在Jackson的单个文件中反序列化来自多个YAML文档的POJO

我有一个YAML文件,看起来像这样:

--- name: Sam tags: - Dev - Java ---- name: Bob tags: - PM 

我想使用Jackson来反序列化文件中的所有文档,但是我没有看到使用普通ObjectMapper来实现它的方法。 如果我使用YAMLFactory为我的文件创建解析器,我可以遍历所有标记,因此解析器显然能够处理多个文档 – 但是如何将它们绑在一起? 看起来我的YAMLFactory创建的解析器只解析文件中的单个文档。

我还尝试直接创建YAMLParser并使用ObjectMapper#readValue(JsonParser, Class) ,但ObjectMapper耗尽整个YAMLParser来反序列化单个实例。

这是几年后,但值得指出,这是支持。 jackson的语义略有不同,可能是因为它的JSON起源。 这可以通过使用ObjectMapperMappingIterator来实现。

 YAMLFactory yaml; ObjectMapper mapper; YAMLParser yamlParser = yaml.createParser("file-with-multiple-docs.yaml") List docs = mapper .readValues(yamlParser, new TypeReference {}) .readAll(); 

如果需要,将ObjectNode替换为您自己的POJO。

你可以直接使用SnakeYaml(Jackson YAML解析器在内部使用它):

 try (InputStream input = new FileInputStream(file)) { Yaml yaml = new Yaml(new SafeConstructor()); yaml.loadAll(input).forEach( System.out::println ); } catch (Throwable e) { System.out.println("ERROR: " + e.getMessage()); } 

将产生:

 {name=Sam, tags=[Dev, Java]} {name=Bob, tags=[PM]} 

目前似乎不支持这一点。 这是YAMLParser源代码的链接。

如果输入YAML包含多个文档,那么Jackson就会失败。 这是一个例子:

 public class JacksonYAML { public static final String YAML = "---\n" + "name: Sam\n" + "tags:\n" + " - Dev\n" + " - Java\n" + "----\n" + "name: Bob\n" + "tags:\n" + " - PM"; public static void main(String[] args) throws IOException { ObjectMapper mapper = new ObjectMapper(new YAMLFactory()); System.out.println(mapper.readValue(YAML, Object.class)); } } 

exception错误指向输入源中的第二项:

 Exception in thread "main" while scanning a simple key in 'reader', line 6, column 1: ---- ^ could not found expected ':' in 'reader', line 7, column 1: name: Bob ^ at com.fasterxml.jackson.dataformat.yaml.snakeyaml.scanner.ScannerImpl.stalePossibleSimpleKeys(ScannerImpl.java:465) at com.fasterxml.jackson.dataformat.yaml.snakeyaml.scanner.ScannerImpl.needMoreTokens(ScannerImpl.java:280) at com.fasterxml.jackson.dataformat.yaml.snakeyaml.scanner.ScannerImpl.checkToken(ScannerImpl.java:225) at com.fasterxml.jackson.dataformat.yaml.snakeyaml.parser.ParserImpl$ParseBlockSequenceEntry.produce(ParserImpl.java:502) at com.fasterxml.jackson.dataformat.yaml.snakeyaml.parser.ParserImpl.peekEvent(ParserImpl.java:158) at com.fasterxml.jackson.dataformat.yaml.snakeyaml.parser.ParserImpl.getEvent(ParserImpl.java:168) at com.fasterxml.jackson.dataformat.yaml.YAMLParser.nextToken(YAMLParser.java:331) at com.fasterxml.jackson.databind.deser.std.UntypedObjectDeserializer$Vanilla.mapArray(UntypedObjectDeserializer.java:529) at com.fasterxml.jackson.databind.deser.std.UntypedObjectDeserializer$Vanilla.deserialize(UntypedObjectDeserializer.java:449) at com.fasterxml.jackson.databind.deser.std.UntypedObjectDeserializer$Vanilla.mapObject(UntypedObjectDeserializer.java:572) at com.fasterxml.jackson.databind.deser.std.UntypedObjectDeserializer$Vanilla.deserialize(UntypedObjectDeserializer.java:435) at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:3051) at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2146) at stackoverflow.JacksonYAML.main(JacksonYAML.java:26) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:606) at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)