Skip to content

@JsonAnySetter mangles nested xml Elements and Attributes during serialization #629

@dudleycodes

Description

@dudleycodes

I apologize in advance if there is already a bug opened for this condition (or if I am approaching this the wrong way) - my search-fu failed to turn up anything similar.

I have a situation where I need deserialize XML to a POJO, and at the end of it all I need to serialize the request back to XML and return it as part of the response. I only need to process a portion the fields. I'd rather not map out all unused fields on the POJO, as this would require constantly updating the application as the end-user's generation of the request schema grows over time.

Describe the bug

I'm attempting to use @JsonAnySetter to capture the unmapped fields during deserialization, and @JsonAnyGetter to serialize them on the way back out.

It works fine for simple values (e.g. <some-unmapped-field>hello</some-unmapped-field>. But when the unmapped field includes attributes (.e.g. <some-unmapped-field id = "one">hello</some-unmapped-field> or nested XML elements (e.g. <some-unmapped-field><a>1</a><b>2</b></some-unmapped-field>, the serialized output becomes completely mangled.

Version information

com.fasterxml.jackson.core:jackson-annotations:2.13.3
com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.13.3

To Reproduce

The POJO:

@Getter
@Setter
public class SomePojo {
     @JsonProperty("id")
     String id;

     /// Other mapped fields/elements....

    @JsonAnyGetter
    @JsonAnySetter
    @JsonUnwrapped
    Map<String, Object> others = new HashMap<>();
}

The input XML:

<some-pojo>
        <id>123</id>
        <unmapped-element>
            <e uid = "1">one</e>
            <e uid = "2">TWO</e>
            <e uid = "3">3</e>
        </unmapped-element>
</some-pojo>

The output XML:

<some-pojo>
     <id>123</id>
     <unmapped-element>
     <e>
                <uid>1</uid><>one
            </>
        </e>
        <e>
            <uid>2</uid><>TWO
        </>
    </e>
    <e>
        <uid>3</uid><>3
    </>
</e>
</unmapped-element>
</some-pojo>
  1. Brief code sample/snippet: include here in preformatted/code section
  2. Longer example stored somewhere else (diff repo, snippet), add a link
  3. Textual explanation: include here

Expected behavior

I would expect the attributes/elements to be kept through the deserialization / serialization process.

Additional context

  • I have tried other values for the underlying map, including String (output is empty) and com.fasterxml.jackson.databind.JsonNode (throws JsonMappingException).
  • I've tried @JsonRawValue, but from what I've read that only affects serialization, and has no effect on deserialization. This has been consistent with my experiments.
  • I've tried writing a custom deserializer, but the underlying JsonParser seems too-JSON oriented, ultimately requiring the input XML to cleanly map to JSON - my guess would be this is why I'm having this issue in the first place.

Thanks for looking!

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions