2008-10-30 118 views
1

我目前正在开发处理SOAP web服务的Java应用程序。在Axis中使用Java中的复杂数据类型webservice

问题在于我解析WSDL [Parser对象来自Apache Axis为我做的事],并创建了调用。

当我尝试调用它时,我必须传递一个Object []来分配参数[取自WSDL的Action]。正常的操作很简单,但是当我有自定义数据类型时,我无法为它填充。我尝试传递Object [] {new Object {}},但它分配了第一个字段。我无法通过它已经处理,因为它将'<>'更改为'--lt --gt',并且服务器无法识别'。

这是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> 

这是麻烦的Java代码片段

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

到目前为止,我认为解决方案可能在于序列化,但即使在实现io.Serializable时,我仍然遇到'NoSerializerFound'。有谁知道我是否可以重写一个方法来告诉它如何序列化它?更新:我可能不得不从org.apache.axis.encoding.ser实现一些对象。任何人? – 2008-10-31 18:02:10

+0

在Serializable接口的Java API中定义,您可以通过实现私有函数writeObject(java.io.ObjectOutputStream)和readObject(java.io.ObjectInputStream)来覆盖它的序列化方式 – Vinze 2008-12-17 15:50:16

回答

1

你有看着使用类似Spring的代理功能?你可以在Spring配置文件中告诉它一些关于web服务的知识,而你所有的客户端代码必须处理的是你创建的一个接口 - 它甚至不需要知道另一端有web服务!

示例Spring配置:

<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(); 
     ... 
    } 
} 

对于自定义对象,你可能需要继承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)); 
    } 
} 

我喜欢这个就是代码不应该关心实施服务的服务不。测试变得轻而易举,并且你的课堂的凝聚力是更好更好。

0

我们试图使用复杂的对象和轴。别! Dotnet能够从WSDL创建一个正确的对象,我们遇到了一堆问题。我们最终只使用了原语,字符串和数组。如果有人有一个使用复杂对象的好方法,我很乐意听到它。