简体   繁体   中英

unmarshalling JSON object to Java without @XMLRootElement

I'm working on JAX-RS with apache-cxf as implementation. I'm having a POST service and getting following 400 error unmarshalling JSON object to Java without @XMLRootElement.

javax.xml.bind.UnmarshalException: unexpected element (uri:"", local:"Customer")

Resource class:

@POST
@Path("/create")
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
@Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
public Response createCustomer(Customer customer) throws Exception {
------
-------
}

JAXB object: doesn't have @XMLRootElement in it.

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Customer", propOrder = {
"id",
"effectiveDate",
"customerType",
"customerName",
 ---
})
public class Customer extends ObjectBase implements Serializable
{

}

ApplicationContext:

<jaxrs:server id="restContainer" address="/">
    <jaxrs:serviceBeans>
        <ref bean="customerResource"/>
    </jaxrs:serviceBeans>       
</jaxrs:server>

JSON

{
"Customer":
{
    "Id": null,
    "ExternalKey": [
        {
            "NaturalKey": "NaturalKey0",
            "KeyName": "KeyName0",
            "SourceSystem": "XYZ"
        },
        {
            "NaturalKey": "NaturalKey1",
            "KeyName": "KeyName1",
            "SourceSystem": "Sys"
        }
    ],
    "MetaData": {
        "ObjectVersion": "50",
        "ObjectState": "Synchronized",
        "CreatedTime": "2006-05-04T18:13:51.0",
        "ModifiedBy": "ModifiedBy0",
        "ModifiedTime": "2006-05-04T18:13:51.0",
        "Verified": "false"
    },
    "EffectiveDate": "2006-05-04",
    "CustomerType": "ABC",
    "CustomerName": "CustomerName0",
    "CustomerTag": [
        {
            "Key": "Customer Number",
            "Value": "Value0"
        },
        {
            "Key": "Customer EID",
            "Value": "Value1"
        }
    ]
}
}

I tried adding Jettison as provider but no luck

I could solve this by adding JAX-RS provider as JSONProvider. In JSONProvider, specify the corresponding namespace for JSON. In this case, I have used empty string.

<util:map id="jsonNamespaceMap" map-class="java.util.Hashtable">
    <entry key="http://www.mycompany.com/abc/xyz/v1" value=""/>
</util:map>

<bean id="jsonProvider" class="org.apache.cxf.jaxrs.provider.JSONProvider"> 
    <property name="namespaceMap" ref="jsonNamespaceMap"/>
    <property name="dropRootElement" value="false"/>
    <property name="ignoreMixedContent" value="true"/>
    <property name="serializeAsArray" value="true"/>
</bean> 

Although i'm yet to find answer for few question which came in my mind -
1. Why do we need JSONProvider in case of POST request only ? For GET request, i could get JSON object as response without adding JSONProvider.
2. If i have @XMLRootElement in customer object, i again don't need JSONProvider and service works, why ?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM