Nitin Bhardwaj created CXF-7791:
-----------------------------------
Summary: Ignoring Namespaces in case of CXF JAX-RS services at the
time of un-marshalling Java objects from JSON
Key: CXF-7791
URL: https://issues.apache.org/jira/browse/CXF-7791
Project: CXF
Issue Type: Bug
Components: JAX-RS
Affects Versions: 3.2.5
Environment: I am using JDK 1.8.0_144, Apache CXF 3.2.5, Tomcat 8.0.5,
and Spring 5.0.4 for this sample project.
Reporter: Nitin Bhardwaj
Attachments: springcxfserver.zip
I want to use the same interface and implementation for exposing the SOAP and
REST web service through CXF. For JAX-WS I want to use the Namespace Qualified
elements in request and response but for JAX-RS I want to ignore the namespaces
for both request/response.
I am using the default Jettison JSON Provider with "ignoreNamespaces" property
set as "true". Have a look at my config:
{color:#205081} *<jaxws:endpoint* id="helloWorld-ws" {color}
{color:#205081} implementor="*com.nit.ws.service.impl.HelloWorldServiceImpl*"
address="/HelloWorldService">{color}
{color:#205081} <jaxws:inInterceptors>{color}
{color:#205081} <ref bean="httpAuthHeaderInterceptor" />{color}
{color:#205081} </jaxws:inInterceptors>{color}
*{color:#205081}</jaxws:endpoint>{color}*
{color:#205081} *<jaxrs:server* id="helloWorld-rs"
address="/helloWorldService">{color}
{color:#205081} <jaxrs:serviceBeans>{color}
{color:#205081} <bean class="*com.nit.ws.service.impl.HelloWorldServiceImpl*"
/>{color}
{color:#205081} </jaxrs:serviceBeans>{color}
{color:#205081}<jaxrs:providers>{color}
{color:#205081} <ref bean="*jsonProvider*" />{color}
{color:#205081} </jaxrs:providers>{color}
{color:#205081} <jaxrs:extensionMappings>{color}
{color:#205081} <entry key="xml" value="application/xml"/>{color}
{color:#205081} <entry key="json" value="application/json"/>{color}
{color:#205081} </jaxrs:extensionMappings>{color}
*{color:#205081}</jaxrs:server>{color}*
{color:#205081} <bean id="httpAuthHeaderInterceptor"
class="com.nit.ws.security.HttpAuthHeaderInterceptor" />{color}
{color:#205081}<bean id="*jsonProvider*"
class="*com.nit.rs.json.StripNamespaceJsonProvider*">{color}
{color:#205081} <property name="*ignoreNamespaces*" value="*true*" />{color}
{color:#205081} </bean>{color}
The *StripNamespaceJsonProvider* simply extends the default CXF's
*JSONProvider* and calls the super class readFrom() and writeTo() methods.
Right now it doesn't have any functionality.
The following is the common *HelloWorldService* interface that I am using for
both JAX-WS and JAX-RS:
*{color:#205081}@WebService{color}*
{color:#205081}public interface *HelloWorldService* {{color}
{color:#205081}......{color}
......
{color:#205081} @WebMethod{color}
{color:#205081} @POST{color}
{color:#205081} @Path("/sampleRequest"){color}
{color:#205081} @Consumes(\{MediaType.APPLICATION_JSON,
MediaType.APPLICATION_XML}){color}
{color:#205081} @Produces(\{MediaType.APPLICATION_JSON,
MediaType.APPLICATION_XML}){color}
*{color:#205081}public OperationResponse
sampleRequest(@WebParam(name="request") OperationRequest request);{color}*
{color:#205081} @WebMethod{color}
{color:#205081} @POST{color}
{color:#205081} @Path("/sampleResponse"){color}
{color:#205081} @Consumes(\{MediaType.APPLICATION_JSON,
MediaType.APPLICATION_XML}){color}
{color:#205081} @Produces(\{MediaType.APPLICATION_JSON,
MediaType.APPLICATION_XML}){color}
*{color:#205081}public OperationResponse sampleResponse();{color}*
{color:#205081}}{color}
The *sampleResponse()* method works because of "*ignoreNamespaces*" property
has been set to "*true*" but not the *sampleRequest(OperationRequest request)*
method.
I used the following request JSON to test the *sampleRequest* method using a
REST client:
{color:#205081}{{color}
{color:#205081} "operationRequest": {{color}
{color:#205081} "operationName": "chottukumaru",{color}
{color:#205081} "payload": "golmamu"{color}
{color:#205081} }{color}
{color:#205081}}{color}
However, it throws up the following exception:
{color:#d04437}16-Jul-2018 18:28:40.205 WARNING [http-nio-8080-exec-2]
org.apache.cxf.jaxrs.provider.AbstractJAXBProvider.handleExceptionStart
javax.xml.bind.UnmarshalException{color}
{color:#d04437} - with linked exception:{color}
{color:#d04437}[com.sun.istack.internal.SAXParseException2; columnNumber: 0;
unexpected element (uri:"", local:"operationRequest"). Expected elements are
<\{http://entity.ws.nit.com/xsd}operationRequest>]{color}
{color:#d04437} at
com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.handleStreamException(UnmarshallerImpl.java:468){color}
{color:#d04437} at
com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:402){color}
{color:#d04437} at
com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:371){color}
{color:#d04437} at
org.apache.cxf.jaxrs.provider.json.JSONProvider.readFrom(JSONProvider.java:242){color}
{color:#d04437} at
com.nit.rs.json.StripNamespaceJsonProvider.readFrom(StripNamespaceJsonProvider.java:61){color}
{color:#d04437} at
org.apache.cxf.jaxrs.utils.JAXRSUtils.readFromMessageBodyReader(JAXRSUtils.java:1354){color}
*The reason* that I found is that the default
*org.apache.cxf.jaxrs.provider.json.JSONProvider* has two methods: *writeTo()*
and *readFrom()*. The writeTo() method uses the property "*ignoreNamespaces*"
to determine if namespaces have to be ignored while marshalling a Java object
to JSON but the readFrom() method doesn't uses the same property to ignore the
namespaces while un-marshalling the JSON into a Java object.
_What approaches do we have to solve this issue? (Not sure if this is even an
issue or am I simply unaware of some other configuration)._
_Do we have this issue for other JSON Providers also like Jackson or Moxy?_
I am attaching my complete web-project as a ready reference.
[^springcxfserver.zip] It can be simply built using maven.
I am using JDK 1.8.0_144, Apache CXF 3.2.5, Tomcat 8.0.5, and Spring 5.0.4 for
this sample project.
--
This message was sent by Atlassian JIRA
(v7.6.3#76005)