Skip to content

MismatchedInputException when deserializing a polymorphic class with JacksonXmlElementWrapper #308

Closed
@ser0l

Description

@ser0l

Using jackson 2.9.6, i get an exception:

com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `java.util.ArrayList` out of VALUE_STRING token

When trying to deserialize a polymorphic object with an arraylist wrapper present, when type attribute is not positioned first in XML. See the following code for an example (incorrectDeserialization test throws the exception):

package com.wrappertest;

import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
import org.junit.Test;

import java.util.ArrayList;
import java.util.Arrays;

import static com.fasterxml.jackson.annotation.JsonSubTypes.*;
import static com.fasterxml.jackson.annotation.JsonTypeInfo.*;
import static org.junit.Assert.assertEquals;

public class ListWrapperWithPolymorphicTypesTest {
    /**************** classes ****************/
    public static class ListWrapper {
        @JacksonXmlElementWrapper(useWrapping = false)
        public ArrayList<Long> item;
    }

    @JsonTypeInfo(use = Id.NAME, include = As.PROPERTY, property = "type")
    @JsonSubTypes({
            @Type(value = ChildClass.class, name = "ChildClass")
    })
    public static abstract class BaseClass {
        public Long baseId;
    }

    public static class ChildClass extends BaseClass {
        public ListWrapper someIds;
    }

    /**************** tests ****************/
    private final XmlMapper xmlMapper = new XmlMapper();

    @Test
    public void correctDeserialization() throws Exception {
        ChildClass value = (ChildClass) xmlMapper.readValue(goodXml(), BaseClass.class);
        doAsserts(value);
    }

    @Test
    public void incorrectDeserialization() throws Exception {
        ChildClass value = (ChildClass) xmlMapper.readValue(badXml(), BaseClass.class);
        doAsserts(value);
    }

    private void doAsserts(ChildClass value) {
        assertEquals(Long.valueOf(123), value.baseId);
        assertEquals(Arrays.asList(1L, 2L), value.someIds.item);
    }

    /** type attribute positioned first, works correctly */
    private String goodXml() {
        return "<root>" +
               "  <type>ChildClass</type>" +
               "  <baseId>123</baseId>" +
               "  <someIds>" +
               "    <item>1</item>" +
               "    <item>2</item>" +
               "  </someIds>" +
               "</root>";
    }

    /** type attribute positioned second, throws exception when parsed */
    private String badXml() {
        return "<root>" +
               "  <baseId>123</baseId>" +
               "  <type>ChildClass</type>" +
               "  <someIds>" +
               "    <item>1</item>" +
               "    <item>2</item>" +
               "  </someIds>" +
               "</root>";
    }
}

Full stack trace

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions