Manuel Ferreria
Manuel Ferreria

Reputation: 1232

Using complex data types from Java in Axis webservice

I am currently developing a Java app which handles a SOAP webservice.

The problem lies after I parse the WSDL [the Parser object from Apache Axis does it for me], and I create the call.

When I try to invoke it, I have to pass a Object[] to assign the parameters [taken from the Action of the WSDL]. A normal action is easy, but when I have custom datatypes, I can't get it to fill it out for me. I try to pass Object[]{ new Object { }}, but it assigns the first field instead. I can't pass it already processed, because it changes the '< >' to '--lt --gt', and the server doesn't recognize it'.

This is a fragment of the WSDL.

  <s:element name="FERecuperaQTYRequest">
    <s:complexType>
      <s:sequence>
        <s:element minOccurs="0" maxOccurs="1" name="argAuth" type="tns:FEAuthRequest" />
      </s:sequence>
    </s:complexType>
  </s:element>
  <s:complexType name="FEAuthRequest">
    <s:sequence>
      <s:element minOccurs="0" maxOccurs="1" name="Token" type="s:string" />
      <s:element minOccurs="0" maxOccurs="1" name="Sign" type="s:string" />
      <s:element minOccurs="1" maxOccurs="1" name="cuit" type="s:long" />
    </s:sequence>
  </s:complexType>

And this is the troublesome Java Fragment

        QTY = (String) call.invoke (
                new Object[]{
                     new Object[]{
                            tokenConexion.getToken (),
                            tokenConexion.getSign (),
                            tokenConexion.getCUIT ()
                                 }
                            });

Upvotes: 1

Views: 7761

Answers (2)

Javamann
Javamann

Reputation: 2912

We tried to use complex objects and Axis. Don't! We had a bunch of problems with Dotnet being able to create a correct object from the WSDL. We ended up just using primitives, strings, and arrays. If someone has a good method of using complex object I would love to hear it.

Upvotes: 0

Chris Marasti-Georg
Chris Marasti-Georg

Reputation: 34650

Have you looked into using something like Spring's proxy functionality? You tell it a bit about the webservice in a spring config file, and all your client code has to deal with is an interface that you create - it doesn't even have to know that there is a web service on the other side!

Example Spring config:

<bean id="myService" class="org.springframework.remoting.jaxrpc.JaxRpcPortProxyFactoryBean">
    <property name="serviceFactoryClass" value="org.apache.axis.client.ServiceFactory"/>
    <property name="wsdlDocumentUrl" value="classpath://META-INF/myService.wsdl"/>
    <property name="namespaceUri" value="http://com/myService"/>
    <property name="endpointAddress" value="http://server/MyService"/>
    <property name="serviceName" value="MyService"/>
    <property name="portName" value="MyService"/>
    <property name="serviceInterface" value="com.IMyService"/>
    <property name="lookupServiceOnStartup" value="false"/>
</bean>
<bean id="myClient" class="com.MyServiceClient">
    <property name="myService" ref="myService"/>
</bean>

Java:

public interface IMyService {
    Foo getFoo();
}

public class MyServiceClient {
    private IMyService myService;
    public void setMyService(IMyService myService) {
        this.myService = myService;
    }

    public void DoStuff() {
        Foo foo = myService.getFoo();
        ...
    }
}

For custom objects, you may need to subclass JaxRpcPortProxyFactoryBean:

public class MyServiceFactoryBean extends JaxRpcPortProxyFactoryBean {
protected void postProcessJaxRpcService(Service service) {
    TypeMappingRegistry registry = service.getTypeMappingRegistry();
    TypeMapping mapping = registry.createTypeMapping();
            QName qName = new QName("http://com/myService", "Foo");
    mapping.register(Foo.class, qName,
            new BeanSerializerFactory(Foo.class, qName),
            new BeanDeserializerFactory(Foo.class, qName));
    }
}

What I love about this is that code that shouldn't care about the implementation of the service doesn't. Testing becomes a breeze, and the cohesion of your classes is much better.

Upvotes: 1

Related Questions