java - Jackson ignores xml root element for abstract class -


i migrating application jersey spring mvc , i'm having problems make jackson work legacy xml's. receive abstract object on request body follow


mycontroller.java

@requestmapping(method = requestmethod.put, value = connectorconstants.subscribe_key) public callable<subscriberesult> subscribe(         @pathvariable final string userkey,         @requestbody(required = false) final subscriberequest subscriberequest) {     return new callable<subscriberesult>()     {         @override         public subscriberesult call() throws exception         {             return someservice.subscribe(userkey, subscriberequest);         }     }; } 

subscriberequest.java

@xmlrootelement(name = "subscribe_request") @xmlseealso({ onerequest.class, anotherrequest.class, simpledomainrequest.class }) public abstract class subscriberequest implements request {      /* (non-javadoc)      * @see com.company.client.request.request#getbody()      */     @override     public abstract <k, v> map<k, v> getbody();      protected final map<object, object> params = new hashmap<object, object>();  } 

simpledomainrequest.java

@xmlaccessortype(xmlaccesstype.field) @xmlrootelement(name = "simple_domain_request") public class simpledomainrequest extends subscriberequest {     ... methods } 

anotherrequest.java

@xmlaccessortype(xmlaccesstype.field) @xmlrootelement(name = "another_request") public class anotherrequest extends subscriberequest {     ... methods } 

onerequest.java

@xmlaccessortype(xmlaccesstype.field) @xmlrootelement(name = "one_request") public class onerequest extends subscriberequest {     ... methods } 

here 1 of xml's controller receives if type of object simpledomainrequest:

<simple_domain_request>   <params>     <entry>         <key             xmlns:xsi="http://www.w3.org/2001/xmlschema-instance"             xmlns:xs="http://www.w3.org/2001/xmlschema" xsi:type="xs:string">my key         </key>         <value             xmlns:xsi="http://www.w3.org/2001/xmlschema-instance"             xmlns:xs="http://www.w3.org/2001/xmlschema" xsi:type="xs:string">my value         </value>     </entry>   </params> </simple_domain_request> 

so except controller part different when using jersey, got code working fine, jersey controller deserializing object without problem. after migrating use spring-mvc , jackson simple can't deserialize it. read jackson doesn't support @xmlseealso tried following changes according guides found on supporting abstract class jackson:

subscriberequest

@xmlrootelement(name = "subscribe_request") @xmlseealso({ onerequest.class, anotherrequest.class, simpledomainrequest.class }) @jsontypeinfo(use = jsontypeinfo.id.name, include = jsontypeinfo.as.wrapper_object) @jsonsubtypes({     @jsonsubtypes.type(value = simpledomainrequest.class, name = "simple_domain_request"),     @jsonsubtypes.type(value = anotherrequest.class, name = "another_request"),     @jsonsubtypes.type(value = onerequest.class, name = "one_request") })    public abstract class subscriberequest implements request {      /* (non-javadoc)      * @see com.company.client.request.request#getbody()      */     @override     public abstract <k, v> map<k, v> getbody();      @jsonproperty     protected final map<object, object> params = new hashmap<object, object>();  } 

but following error jackson: could not resolve type id 'params'

caused by: com.fasterxml.jackson.databind.jsonmappingexception: not resolve type id 'params' subtype of [simple type, class com.company.subscriberequest]: known type ids = [subscriberequest, one_request, simple_domain_request, another_request] @ [source: java.io.pushbackinputstream@55416df4; line: 4, column: 13] @ com.fasterxml.jackson.databind.jsonmappingexception.from(jsonmappingexception.java:148) ~[jackson-databind-2.5.1.jar:2.5.1] @ com.fasterxml.jackson.databind.deserializationcontext.unknowntypeexception(deserializationcontext.java:948) ~[jackson-databind-2.5.1.jar:2.5.1] @ com.fasterxml.jackson.databind.jsontype.impl.typedeserializerbase._handleunknowntypeid(typedeserializerbase.java:275) ~[jackson-databind-2.5.1.jar:2.5.1] @ com.fasterxml.jackson.databind.jsontype.impl.typedeserializerbase._finddeserializer(typedeserializerbase.java:162) ~[jackson-databind-2.5.1.jar:2.5.1] @ com.fasterxml.jackson.databind.jsontype.impl.aswrappertypedeserializer._deserialize(aswrappertypedeserializer.java:100) ~[jackson-databind-2.5.1.jar:2.5.1] @ com.fasterxml.jackson.databind.jsontype.impl.aswrappertypedeserializer.deserializetypedfromobject(aswrappertypedeserializer.java:49) ~[jackson-databind-2.5.1.jar:2.5.1] @ com.fasterxml.jackson.databind.deser.abstractdeserializer.deserializewithtype(abstractdeserializer.java:131) ~[jackson-databind-2.5.1.jar:2.5.1] @ com.fasterxml.jackson.databind.deser.impl.typewrappeddeserializer.deserialize(typewrappeddeserializer.java:42) ~[jackson-databind-2.5.1.jar:2.5.1] @ com.fasterxml.jackson.databind.objectmapper._readmapandclose(objectmapper.java:3562) ~[jackson-databind-2.5.1.jar:2.5.1] @ com.fasterxml.jackson.databind.objectmapper.readvalue(objectmapper.java:2662) ~[jackson-databind-2.5.1.jar:2.5.1] @ org.springframework.http.converter.json.abstractjackson2httpmessageconverter.readjavatype(abstractjackson2httpmessageconverter.java:205) ~[spring-web-4.1.5.release.jar:4.1.5.release] 

this message converters configuration:

public class webconfigurationadapter extends webmvcconfigureradapter { @override public void configuremessageconverters(list<httpmessageconverter<?>> converters) {     jackson2objectmapperbuilder builder = new jackson2objectmapperbuilder();     builder.featurestoenable(mapperfeature.default_view_inclusion);     converters.add(new mappingjackson2httpmessageconverter(builder.build()));     converters.add(new mappingjackson2xmlhttpmessageconverter(builder.createxmlmapper(true).build())); } 

if change use unwrap_root_value

builder.featurestoenable(mapperfeature.default_view_inclusion, deserializationfeature.unwrap_root_value); 

then error:

caused by: com.fasterxml.jackson.databind.jsonmappingexception: root name 'params' not match expected ('subscriberequest') type [simple type, class com.company.subscriberequest] 

if request body wrapped in xml tag works:

<any_name_here_doesnt_matter>  <simple_domain_request>   <params>     <entry>         <key             xmlns:xsi="http://www.w3.org/2001/xmlschema-instance"             xmlns:xs="http://www.w3.org/2001/xmlschema" xsi:type="xs:string">my key         </key>         <value             xmlns:xsi="http://www.w3.org/2001/xmlschema-instance"             xmlns:xs="http://www.w3.org/2001/xmlschema" xsi:type="xs:string">my value         </value>     </entry>   </params>  </simple_domain_request> </any_name_here_doesnt_matter> 

please keep in mind thought have access subscriberequest class need mantain compatibility, can't change xml receive. default_view_inclusion there because use jsonview other objects.

i might missing obvious here appreciated or if need see more of code.

pom.xml declaring jackson

<properties>     <woodstox-core-asl.version>4.4.1</woodstox-core-asl.version>     <jackson.version>2.5.1</jackson.version> </properties>      <!-- jackson -->     <dependency>         <groupid>com.fasterxml.jackson.core</groupid>         <artifactid>jackson-databind</artifactid>         <version>${jackson.version}</version>     </dependency>     <dependency>         <groupid>com.fasterxml.jackson.dataformat</groupid>         <artifactid>jackson-dataformat-xml</artifactid>         <version>${jackson.version}</version>     </dependency>     <dependency>         <groupid>org.codehaus.woodstox</groupid>         <artifactid>woodstox-core-asl</artifactid>         <version>${woodstox-core-asl.version}</version>     </dependency> 

spring version 4.1.5.

use @jacksonxmlrootelement(localname = "simple_domain_request" annotation instead of @xmlrootelement(name = "simple_domain_request")


Comments

Popular posts from this blog

node.js - Mongoose: Cast to ObjectId failed for value on newly created object after setting the value -

gradle error "Cannot convert the provided notation to a File or URI" -

python - NameError: name 'subprocess' is not defined -