Uploaded image for project: 'CXF'
  1. CXF
  2. CXF-7791

How to ignore Namespaces in case of CXF JAX-RS services at the time of un-marshalling Java objects from JSON

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Closed
    • Major
    • Resolution: Information Provided
    • 3.2.5
    • None
    • JAX-RS, JAXB Databinding
    • None
    • 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.

    • Unknown

    Description

      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:

      <jaxws:endpoint id="helloWorld-ws"
      implementor="com.nit.ws.service.impl.HelloWorldServiceImpl" address="/HelloWorldService">
      <jaxws:inInterceptors>
      <ref bean="httpAuthHeaderInterceptor" />
      </jaxws:inInterceptors>
      </jaxws:endpoint>

      <jaxrs:server id="helloWorld-rs" address="/helloWorldService">
      <jaxrs:serviceBeans>
      <bean class="com.nit.ws.service.impl.HelloWorldServiceImpl" />
      </jaxrs:serviceBeans>
      <jaxrs:providers>
      <ref bean="jsonProvider" />
      </jaxrs:providers>
      <jaxrs:extensionMappings>
      <entry key="xml" value="application/xml"/>
      <entry key="json" value="application/json"/>
      </jaxrs:extensionMappings>
      </jaxrs:server>

      <bean id="httpAuthHeaderInterceptor" class="com.nit.ws.security.HttpAuthHeaderInterceptor" />

      <bean id="jsonProvider" class="com.nit.rs.json.StripNamespaceJsonProvider">
      <property name="ignoreNamespaces" value="true" />
      </bean>

      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:

      @WebService
      public interface HelloWorldService {

      ......

      ......
      @WebMethod
      @POST
      @Path("/sampleRequest")
      @Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
      @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
      public OperationResponse sampleRequest(@WebParam(name="request") OperationRequest request);

      @WebMethod
      @POST
      @Path("/sampleResponse")
      @Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
      @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
      public OperationResponse sampleResponse();
      {color:#205081}}

       

      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:

      {
             "operationRequest": {
             "operationName": "chottukumaru",
             "payload": "golmamu"
             }
      {color:#205081}}

      However, it throws up the following exception:

      16-Jul-2018 18:28:40.205 WARNING [http-nio-8080-exec-2] org.apache.cxf.jaxrs.provider.AbstractJAXBProvider.handleExceptionStart javax.xml.bind.UnmarshalException
      - with linked exception:
      [com.sun.istack.internal.SAXParseException2; columnNumber: 0; unexpected element (uri:"", local:"operationRequest"). Expected elements are <\\{http://entity.ws.nit.com/xsd}operationRequest>]
      at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.handleStreamException(UnmarshallerImpl.java:468)
      at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:402)
      at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:371)
      at org.apache.cxf.jaxrs.provider.json.JSONProvider.readFrom(JSONProvider.java:242)
      at com.nit.rs.json.StripNamespaceJsonProvider.readFrom(StripNamespaceJsonProvider.java:61)
      at org.apache.cxf.jaxrs.utils.JAXRSUtils.readFromMessageBodyReader(JAXRSUtils.java:1354)

      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.

       

       

       

      Attachments

        1. springcxfserver.zip
          21 kB
          Nitin Bhardwaj

        Activity

          People

            coheigea Colm O hEigeartaigh
            NitinBhardwaj Nitin Bhardwaj
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: