Francesco
Francesco

Reputation: 1802

AXIS Client v.s. AXIS2 Service

I must implement an AXIS 1.4 client which consume an AXIS2 1.4 method. AXIS 1.4 client is made by creating the stubs. The client send a request and get back a response from service with some attachment (MTOM). When I call the method (operation) by AXIS 1.4 port type object I got an error:

org.xml.sax.SAXException: SimpleDeserializer encountered a child element, which is NOT expected, in something it was trying to deserialize.

I think MTOM messed up with AXIS. So here is the question: how did I get the attachment the AXIS2 1.4 (MTOM) web service return me back? TIA.

Francesco

P.S: here is the code. There are stubs generated by WSDL. The problem is: i get the exception when I call the port's stub method. There are attachments in the message I get back.

String codistat = "CODISTAT";    
OrdinanzeViabilitaLocator ovlocretreive = new OrdinanzeViabilitaLocator();
ovlocretreive.setOrdinanzeViabilitaHttpSoap11EndpointEndpointAddress(".. the service url + action..");
try {
  OrdinanzeViabilitaPortType ovretreive = ovlocretreive.getOrdinanzeViabilitaHttpSoap11Endpoint();
  ((Stub) ovretreive)._setProperty(javax.xml.rpc.Call.USERNAME_PROPERTY, "username");
  ((Stub) ovretreive)._setProperty(javax.xml.rpc.Call.PASSWORD_PROPERTY, "password");            
  //problems began here
  MessageReqOrdinanze mrq = new MessageReqOrdinanze();
  mrq.setCodistat(codistat);
  Calendar date_from = Calendar.getInstance();
  date_from.setTimeInMillis(0);
  Calendar date_to = Calendar.getInstance();
  date_from.setTimeInMillis(0);
  mrq.setDate_from(date_from);
  mrq.setDate_to(date_to);
  // the next line generate the exception
  MessageOrdinanze mretreive = ovretreive.getOrdinanze(mrq);
  } catch (AxisFault e) {
        e.printStackTrace();
  } catch (RemoteException e) {
        e.printStackTrace();
  } catch (FileNotFoundException e) {
        e.printStackTrace();
  } catch (IOException e) {
        e.printStackTrace();
  } catch (ServiceException e) {
        e.printStackTrace();
  }

The message I get back has a

<xop:include href="cid... >...< ../xop/include"/>

tag inside, it's MTOM (it cause the exception I guess). Hope this helps.

Upvotes: 3

Views: 4503

Answers (3)

Fabio Parise
Fabio Parise

Reputation: 1

In the above solution, point 2) can be achieved without the need of the client-config.wsdd file, using with the following java code in the call in the BindingStub class:

org.apache.axis.client.Call call ...
...
call.setEncodingStyle(null); // Allows use of JAFDataHandlerSerializer
call.registerTypeMapping(DataHandler.class, new QName("http://schemas.xmlsoap.org/soap/encoding/", "base64Binary"), JAFDataHandlerSerializerFactory.class, JAFDataHandlerDeserializerFactory.class);

Upvotes: 0

user1289117
user1289117

Reputation: 115

Above solution is great. However those who might be struggling to make above code snippet work, please use xmlns:xs="http://www.w3.org/2001/XMLSchema", then only given typeMapping snippet works.

<typeMapping qname="xs:base64Binary" languageSpecificType="java:javax.activation.DataHandler"
deserializer="org.apache.axis.encoding.ser.JAFDataHandlerDeserializerFactory"
    serializer="org.apache.axis.encoding.ser.JAFDataHandlerSerializerFactory"
    xmlns:xs="http://www.w3.org/2001/XMLSchema" encodingStyle="" />

Upvotes: 0

Andreas Veithen
Andreas Veithen

Reputation: 9154

There are two things that need to be done to make MTOM work on the client side:

  1. Ensure that in the stubs, the xs:base64Binary type is mapped to java.activation.DataHandler instead of byte[].
  2. Set up a (runtime) type mapping for xs:base64Binary and java.activation.DataHandler that uses JAFDataHandlerSerializer and JAFDataHandlerDeserializer (which support MTOM).

The second part is fairly easy. Simply set up a client-config.wsddfile with the following type mapping:

<typeMapping languageSpecificType="java:javax.activation.DataHandler" qname="xs:base64Binary"
             deserializer="org.apache.axis.encoding.ser.JAFDataHandlerDeserializerFactory"
             serializer="org.apache.axis.encoding.ser.JAFDataHandlerSerializerFactory" 
             encodingStyle=""/>

The first part is more tricky because the tooling (wsdl2java) in Axis 1.4 doesn't support changing the Java type associated with a given XML type. There are several ways to work around that limitation:

  • Edit the generated stubs by hand and change byte[] to javax.activation.DataHandler. Depending on how you manage generated code in your project, that may or may not be an acceptable solution.
  • It is probably possible (although I didn't test that) to trick wsdl2java into using javax.activation.DataHandler by giving it a modified WSDL where the type {http://www.w3.org/2001/XMLSchema}base64Binary is replaced by {java}javax.activation.DataHandler.
  • I fixed the tooling in the current Axis trunk so that it supports this type of configuration. Note however that this is only implemented in the wsdl2java Maven plugin (but not in the Ant task or the command line tool). You could use the 1.4.1-SNAPSHOT version of that plugin; the generated code would still work with Axis 1.4. You can find some documentation here.

Upvotes: 5

Related Questions