Hello,


I have a simple XSD file. From that file, we generate Java Objects using 
XJC. We want to serialize and deserialize such objects to XML (which 
worked) and to JSON. A valid XML looks like this:


<user>
    <loginId>demo</loginId>
    <roles>
        <role>ADMIN</role>
        <role>USER</role>
    </roles></user>

If we use Jackson (version 2.9.0) to generate a JSON String out of the 
JAX-B class, without any Mixin Configuration, it will look like this:

{
    "loginId": "demo",
    "roles": {
        "role": ["ADMIN","USER"]
    }}

To avoid the "roles"/"role" construct, we use a Mixin to get the following 
result:

{
    "loginId": "demo",
    "roles": ["ADMIN", "USER"]}

This worked for the serialization process, but not for deserialization.

Here is the code, we use to configure the Mapper and to test the 
deserialization:


public class JSONSupportTest {

    private static final String USER_JSON = "{\n"
        + "    \"loginId\": \"demo\",\n"
        + "    \"roles\": [\n"
        + "        \"ADMIN\",\n"
        + "        \"USER\"\n"
        + "    ]\n"
        + "}";

    @Test
    public void testJSONDeserialization() throws Exception {

        ObjectMapper mapper = new ObjectMapper();
        mapper.configure(SerializationFeature.WRAP_ROOT_VALUE, false);
        mapper.setSerializationInclusion(Include.NON_NULL);    
        mapper.addMixIn(JAXBElement.class, JaxBElementMixin.class);
        mapper.addMixIn(Roles.class, UserRolesMixin.class); // this line avoids 
the "roles"/"role" construct

        UserType result = mapper.readValue(USER_JSON, UserType.class);
        System.out.println(result);
    }}

With that code, we run in the following exception:

com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize 
instance of de.demo.UserType$Roles out of START_ARRAY token
 at [Source: (String)"{
"loginId": "demo",
"roles": [
    "ADMIN",
    "USER"
]
}"; line: 3, column: 14] (through reference chain: de.demo.UserType["roles"])
at 
com.fasterxml.jackson.databind.exc.MismatchedInputException.from(MismatchedInputException.java:63)
at 
com.fasterxml.jackson.databind.DeserializationContext.reportInputMismatch(DeserializationContext.java:1329)
at 
com.fasterxml.jackson.databind.DeserializationContext.handleUnexpectedToken(DeserializationContext.java:1138)
at 
com.fasterxml.jackson.databind.DeserializationContext.handleUnexpectedToken(DeserializationContext.java:1092)
at 
com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromArray(BeanDeserializerBase.java:1439)
at 
com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeOther(BeanDeserializer.java:185)
at 
com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:161)
at 
com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:127)
at 
com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:287)
at 
com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:151)
at 
com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4001)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2992)
at de.demo.JSONSupportTest.testJSONDeserialization(JSONSupportTest.java:22)


Is there a way, that Jackson supports both ways (serialization and 
deserialization)?


Here is the full code:


*The XSD File:*

<schema xmlns:tns="http://demo.de"; elementFormDefault="qualified"
    targetNamespace="http://demo.de"; version="2.0"
    xmlns="http://www.w3.org/2001/XMLSchema";>
<element name="user" type="tns:UserType"/>
<complexType name="UserType">
    <sequence>
        <element minOccurs="1" maxOccurs="1" name="loginId" type="string" />
        <element maxOccurs="1" minOccurs="1" name="roles">
            <complexType>
                <sequence>
                    <element maxOccurs="unbounded" minOccurs="1" name="role" 
type="tns:RoleType" />
                </sequence>
            </complexType>
        </element>
    </sequence></complexType>

<simpleType name="RoleType">
    <restriction base="string">
        <enumeration value="USER" />
        <enumeration value="ADMIN" />
    </restriction></simpleType>


*The JAX-B Classes generated by XJC:*


@XmlAccessorType(XmlAccessType.FIELD)@XmlType(name = "UserType", propOrder = {
    "loginId",
    "roles"})public class UserType {
    @XmlElement(required = true)
    protected String loginId;
    @XmlElement(required = true)
    protected UserType.Roles roles;

    public String getLoginId() {
        return loginId;
    }

    public void setLoginId(String value) {
        this.loginId = value;
    }

    public UserType.Roles getRoles() {
        return roles;
    }

    public void setRoles(UserType.Roles value) {
        this.roles = value;
    }

    @XmlAccessorType(XmlAccessType.FIELD)
    @XmlType(name = "", propOrder = {
        "role"
    })
    public static class Roles {

        @XmlElement(required = true)
        @XmlSchemaType(name = "string")
        protected List<RoleType> role;

        public List<RoleType> getRole() {
            if (role == null) {
                role = new ArrayList<RoleType>();
            }
            return this.role;
        }
    }}

@XmlType(name = "RoleType")@XmlEnumpublic enum RoleType {

    USER,
    ADMIN;

    public String value() {
        return name();
    }

    public static RoleType fromValue(String v) {
        return valueOf(v);
    }}

*And finally the Mixin class for the roles part*


public class UserRolesMixin extends Roles{

    @JsonValue
    @Override
    public List<RoleType> getRole() {
        return super.getRole();
    }}

I have not find out what is wrong with the code. Why does it only work in the 
serialization case and not in deserialization?

Thanks a lot

-- 
You received this message because you are subscribed to the Google Groups 
"jackson-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to