Skip to content

@JsonAnySetter Mangles Nested Xml Elements and Xml Attributes During Serialization #629

Open
@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

    to-evaluateIssue that has been received but not yet evaluated

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions