'Serializing multiline string from JsonNode to YAML string adds double quotes and "\n"

I have a YAML string where one of the attributes looks like this:

 description: |
    this is my description  //imagine there's a space after description
    this is my description in the second line

In my Java code I read it into a JsonNode like this:

JsonNode node = new YamlMapper().readTree(yamlString);

I then do some changes to it and write it back to a string like this:

new YamlMapper().writeValueAsString(node))

The new string now looks like this:

"this is my description \nthis is my description in the second line\n"

So now in the YAML file you can see the added quotes + the new line character (\n) and everything is in one line. I expect it to return the original YAML like the one above.

This is how my YAML object mapper is configured:

 new ObjectMapper(
        new YAMLFactory()
          .disable(YAMLGenerator.Feature.MINIMIZE_QUOTES))
        .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
        .setSerializationInclusion(JsonInclude.Include.NON_EMPTY);

If I remove the space after description in the original YAML, it works just fine



Solution 1:[1]

Jackson's API is too high level to control the output in detail. You can use SnakeYAML directly (which is used by Jackson under the hood), but you need to go down to the node or event level of the API to control node style in the output.

See also: I want to load a YAML file, possibly edit the data, and then dump it again. How can I preserve formatting?

This answer shows general usage of SnakeYAML's event API to keep formatting; of course it's harder to do changes on a stream of events. You might instead want to work on the node graph, this answer has some example code showing how to load YAML to a node graph, process it, and write it back again.

Solution 2:[2]

To serialize multiline text using jackson. Jackson introduced a new flag YAMLGenerator.Feature.LITERAL_BLOCK_STYLE since version 2.9, which can be turned on as:

new ObjectMapper(
    new YAMLFactory().enable(YAMLGenerator.Feature.LITERAL_BLOCK_STYLE)
).writeValueAsString(new HashMap<String, String>(){{
    put("key", "test1\ntest2\ntest3");
}});

The output won't be wrapped with quotes:

---
key: |-
  test1
  test2
  test3

Note there is a few differences between "block scalars": |, |-, >..., you can check out at https://yaml-multiline.info/

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 flyx
Solution 2 AssKicker