2009-06-16 90 views
2

更新:我现在已经解决了这个问题 - 请滚动到底以获取有关FIX即使SOAP请求被正确发送,Axis2也总是接收空参数?

家伙嗨,

我有一个Web服务用Java编写的,托管在一个Axis2/Tomcat的/阿帕奇服务器。我的客户端软件是用C#编写的。

我对java2wsdl生成wsdl文件的方式有些恼人的问题,这在早期确实引起了我的一些头痛,但是这个问题我完全陷入了困境。

基本上,发生的事情是客户端看到Web服务正常,并向参数发送一个完全有效的(或者至少对我看来是有效的)SOAP请求。

在服务器上,执行正确的Web方法,但参数全为空。我的网络服务检测到这一点,并建立一个响应,客户收到并理解得非常好。

我的直觉是,Axis2的是在其表面平坦的地方坠落,但由于头痛我曾与的Java2WSDL,也许我需要的是在我的WSDL文件的变化。

这里是WSDL文件:

<?xml version="1.0" encoding="UTF-8"?> 
<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:axis2="http://stws/" xmlns:ns1="http://org.apache.axis2/xsd" xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:ns0="http://stws/xsd" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" targetNamespace="http://stws/"> 
    <wsdl:types> 
     <xs:schema xmlns:ns="http://stws/xsd" attributeFormDefault="qualified" elementFormDefault="qualified" targetNamespace="http://stws/xsd"> 
      <xs:element name="GetGroups"> 
       <xs:complexType> 
        <xs:sequence> 
         <xs:element minOccurs="0" name="serialcode" nillable="true" type="xs:string"/> 
        </xs:sequence> 
       </xs:complexType> 
      </xs:element> 
      <xs:element name="GetGroupsResponse"> 
       <xs:complexType> 
        <xs:sequence> 
         <xs:element maxOccurs="unbounded" minOccurs="0" name="return" nillable="true" type="ns0:Group"/> 
        </xs:sequence> 
       </xs:complexType> 
      </xs:element> 
      <xs:complexType name="Group"> 
       <xs:sequence> 
        <xs:element minOccurs="0" name="ID" type="xs:int"/> 
        <xs:element minOccurs="0" name="Name" nillable="true" type="xs:string"/> 
       </xs:sequence> 
      </xs:complexType> 
      <xs:element name="GetMessages"> 
       <xs:complexType> 
        <xs:sequence> 
         <xs:element minOccurs="0" name="serialcode" nillable="true" type="xs:string"/> 
         <xs:element maxOccurs="unbounded" minOccurs="0" name="groupids" type="xs:int"/> 
        </xs:sequence> 
       </xs:complexType> 
      </xs:element> 
      <xs:element name="GetMessagesResponse"> 
       <xs:complexType> 
        <xs:sequence> 
         <xs:element maxOccurs="unbounded" minOccurs="0" name="return" nillable="true" type="ns0:Message"/> 
        </xs:sequence> 
       </xs:complexType> 
      </xs:element> 
      <xs:complexType name="Message"> 
       <xs:sequence> 
        <xs:element minOccurs="0" name="date" nillable="true" type="xs:string"/> 
        <xs:element minOccurs="0" name="group" type="xs:int"/> 
        <xs:element minOccurs="0" name="messageID" type="xs:int"/> 
        <xs:element minOccurs="0" name="text" nillable="true" type="xs:string"/> 
       </xs:sequence> 
      </xs:complexType> 
     </xs:schema> 
    </wsdl:types> 
    <wsdl:message name="GetMessagesRequest"> 
     <wsdl:part name="parameters" element="ns0:GetMessages"/> 
    </wsdl:message> 
    <wsdl:message name="GetMessagesResponse"> 
     <wsdl:part name="parameters" element="ns0:GetMessagesResponse"/> 
    </wsdl:message> 
    <wsdl:message name="GetGroupsRequest"> 
     <wsdl:part name="parameters" element="ns0:GetGroups"/> 
    </wsdl:message> 
    <wsdl:message name="GetGroupsResponse"> 
     <wsdl:part name="parameters" element="ns0:GetGroupsResponse"/> 
    </wsdl:message> 
    <wsdl:portType name="MyProjectPortType"> 
     <wsdl:operation name="GetMessages"> 
      <wsdl:input message="axis2:GetMessagesRequest" wsaw:Action="urn:GetMessages"/> 
      <wsdl:output message="axis2:GetMessagesResponse" wsaw:Action="urn:GetMessagesResponse"/> 
     </wsdl:operation> 
     <wsdl:operation name="GetGroups"> 
      <wsdl:input message="axis2:GetGroupsRequest" wsaw:Action="urn:GetGroups"/> 
      <wsdl:output message="axis2:GetGroupsResponse" wsaw:Action="urn:GetGroupsResponse"/> 
     </wsdl:operation> 
    </wsdl:portType> 
    <wsdl:binding name="MyProjectSOAP11Binding" type="axis2:MyProjectPortType"> 
     <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/> 
     <wsdl:operation name="GetMessages"> 
      <soap:operation soapAction="urn:GetMessages" style="document"/> 
      <wsdl:input> 
       <soap:body use="literal"/> 
      </wsdl:input> 
      <wsdl:output> 
       <soap:body use="literal"/> 
      </wsdl:output> 
     </wsdl:operation> 
     <wsdl:operation name="GetGroups"> 
      <soap:operation soapAction="urn:GetGroups" style="document"/> 
      <wsdl:input> 
       <soap:body use="literal"/> 
      </wsdl:input> 
      <wsdl:output> 
       <soap:body use="literal"/> 
      </wsdl:output> 
     </wsdl:operation> 
    </wsdl:binding> 
    <wsdl:binding name="MyProjectSOAP12Binding" type="axis2:MyProjectPortType"> 
     <soap12:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/> 
     <wsdl:operation name="GetMessages"> 
      <soap12:operation soapAction="urn:GetMessages" style="document"/> 
      <wsdl:input> 
       <soap12:body use="literal"/> 
      </wsdl:input> 
      <wsdl:output> 
       <soap12:body use="literal"/> 
      </wsdl:output> 
     </wsdl:operation> 
     <wsdl:operation name="GetGroups"> 
      <soap12:operation soapAction="urn:GetGroups" style="document"/> 
      <wsdl:input> 
       <soap12:body use="literal"/> 
      </wsdl:input> 
      <wsdl:output> 
       <soap12:body use="literal"/> 
      </wsdl:output> 
     </wsdl:operation> 
    </wsdl:binding> 
    <wsdl:binding name="MyProjectHttpBinding" type="axis2:MyProjectPortType"> 
     <http:binding verb="POST"/> 
     <wsdl:operation name="GetMessages"> 
      <http:operation location="MyProject/GetMessages"/> 
      <wsdl:input> 
       <mime:content type="text/xml" part="GetMessages"/> 
      </wsdl:input> 
      <wsdl:output> 
       <mime:content type="text/xml" part="GetMessages"/> 
      </wsdl:output> 
     </wsdl:operation> 
     <wsdl:operation name="GetGroups"> 
      <http:operation location="MyProject/GetGroups"/> 
      <wsdl:input> 
       <mime:content type="text/xml" part="GetGroups"/> 
      </wsdl:input> 
      <wsdl:output> 
       <mime:content type="text/xml" part="GetGroups"/> 
      </wsdl:output> 
     </wsdl:operation> 
    </wsdl:binding> 
    <wsdl:service name="MyProject"> 
     <wsdl:port name="MyProjectSOAP11port_http" binding="axis2:MyProjectSOAP11Binding"> 
      <soap:address location="http://localhost:8080/axis2/services/MyProject"/> 
     </wsdl:port> 
     <wsdl:port name="MyProjectSOAP12port_http" binding="axis2:MyProjectSOAP12Binding"> 
      <soap12:address location="http://localhost:8080/axis2/services/MyProject"/> 
     </wsdl:port> 
     <wsdl:port name="MyProjectHttpport" binding="axis2:MyProjectHttpBinding"> 
      <http:address location="http://localhost:8080/axis2/services/MyProject"/> 
     </wsdl:port> 
    </wsdl:service> 
</wsdl:definitions> 

这里是一个示例请求和响应:

请求:

<?xml version='1.0' encoding='utf-8'?> 
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <soap:Body> 
    <GetGroups xmlns="http://stws/xsd"> 
     <serialcode>123456-654321</serialcode> 
    </GetGroups> 
    </soap:Body> 
</soap:Envelope> 

响应

<?xml version='1.0' encoding='utf-8'?> 
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> 
    <soapenv:Body> 
    <GetGroupsResponse xmlns="http://stws/xsd"> 
     <return> 
     <ID>-101</ID> 
     <name>ERROR: Empty Serial</name> 
     </return> 
    </GetGroupsResponse> 
    </soapenv:Body> 
</soapenv:Envelope> 

有谁知道任何想法会发生什么问题?

响应中的错误消息只能在请求中的serialcode参数为空/空时发送,所以我猜测Axis2如何读取我的参数时出现错误。

任何帮助,非常感谢。

============================================== ==============

如何解决这一问题:

这是响应奥尔多的请求,我怎么解决了这个问题的详细信息。

我不确定为什么这个修补程序有效 - 也许它只是Axis2中的一个错误。无论哪种方式,YMMV,因为我不知道问题是否是由我的设置或其他东西引起的。我只能说,通过以下操作,一切都开始奏效。

无论如何,自动生成的WSDL文件为Web请求及其参数创建复杂元素类型,即使只有参数是简单类型(如字符串或整数)时也是如此。我所做的是为参数创建正确的简单类型标记(例如'serialcode'或'date-string'),然后用对简单类型的引用替换WSDL文件中其他位置的复杂类型的引用。

下面是一个例子:

自动生成WSDL方法和参数

<!--Requests-->  
<wsdl:message name="RegisterClientRequest"> 
    <wsdl:part name="parameters" element="ns0:RegisterClient"/> 
</wsdl:message> 
<wsdl:message name="GetGroupsRequest"> 
    <wsdl:part name="parameters" element="ns0:GetGroups"/> 
</wsdl:message> 

<!--Parameters--> 
<xs:element name="RegisterClient"> 
    <xs:complexType> 
     <xs:sequence> 
      <xs:element minOccurs="0" name="serialcode" nillable="true" type="xs:string"/> 
     </xs:sequence> 
    </xs:complexType> 
</xs:element> 
<xs:element name="GetGroups"> 
    <xs:complexType> 
     <xs:sequence> 
      <xs:element minOccurs="0" name="serialcode" nillable="true" type="xs:string"/> 
     </xs:sequence> 
    </xs:complexType> 
</xs:element> 

基本上你应该做的是放弃自动生成的参数,并创建简单的类型。然后修改'request'标签以使用'type'而不是'element',并使用新创建的简单类型。

修改/固定WSDL

<!--Requests-->  
<wsdl:message name="RegisterClientRequest"> 
    <wsdl:part name="parameters" type="ns0:SerialCode"/> 
</wsdl:message> 
<wsdl:message name="GetGroupsRequest"> 
    <wsdl:part name="parameters" type="ns0:SerialCode"/> 
</wsdl:message> 

<!--Parameters--> 
<xs:simpleType name="SerialCode"> 
    <xs:restriction base="xs:string"/> 
</xs:simpleType> 

显然,这取决于你的参数其实都是。在我的情况下,它们都是标准的简单类型,如字符串和整数。如果传递多个参数,则可能需要保留自动生成的元素,但确保元素引用的是简单类型,而不是仅将type属性包含为“xs:string”或其他类型的属性。

道歉我不能更清楚这一点,但正如我之前所说 - 我不知道为什么这个工程。

最后一件事:通过删除请求标记中的'element'引用属性 - 您可能会在Axis2日志中收到解析器警告。到目前为止,这并没有给我带来任何问题,但如果你遇到麻烦的话,应该注意。

+0

什么组件正在进行验证并生成错误消息?如果它是你的代码,你可以验证请求数据到达那么远时的时间吗? – skaffman 2009-06-16 11:58:27

+0

实际的Web方法本身执行一个快速检查(事实上,检查首先存在的唯一原因是因为我获得了空返回 - 这只是让我一个简单的方法来确认输入为空!)。 Web服务代码上的简单单元测试不会产生这个问题,并且Axis2自己的SOAPMonitor显示客户端确实正在发送所需参数 - 但由于某些原因,在Axis2调用Web方法时这些参数被取消。 – Beardy 2009-06-16 12:44:03

回答

1

我通过浏览我的WSDL文件解决了这个问题,并在可能的情况下将元素分解为简单类型的对应元素,并相应地更新XML元素之间的引用。

我不确定为什么这个工作,但它已经解决了我的问题。

0

这只是一个预感,但也许你有一个命名空间问题。如果您专注于wsdl的这一部分,请注意您的参数对于元素有一个“ns0”命名空间,但在稍后定义的操作中,它看起来像使用了“axis2”命名空间。用我所有的Axis2生成的WSDLs,这两个命名空间是相同的。

<wsdl:message name="GetMessagesRequest"> 
    <wsdl:part name="parameters" element="ns0:GetMessages"/> 
</wsdl:message> 
<wsdl:message name="GetMessagesResponse"> 
    <wsdl:part name="parameters" element="ns0:GetMessagesResponse"/> 
</wsdl:message> 
<wsdl:message name="GetGroupsRequest"> 
    <wsdl:part name="parameters" element="ns0:GetGroups"/> 
</wsdl:message> 
<wsdl:message name="GetGroupsResponse"> 
    <wsdl:part name="parameters" element="ns0:GetGroupsResponse"/> 
</wsdl:message> 

<wsdl:portType name="MyProjectPortType"> 
    <wsdl:operation name="GetMessages"> 
     <wsdl:input message="axis2:GetMessagesRequest" wsaw:Action="urn:GetMessages"/> 
     <wsdl:output message="axis2:GetMessagesResponse" wsaw:Action="urn:GetMessagesResponse"/> 
    </wsdl:operation> 
    <wsdl:operation name="GetGroups"> 
     <wsdl:input message="axis2:GetGroupsRequest" wsaw:Action="urn:GetGroups"/> 
     <wsdl:output message="axis2:GetGroupsResponse" wsaw:Action="urn:GetGroupsResponse"/> 
    </wsdl:operation> 
</wsdl:portType> 

您可以检查的另一件事是验证您从java2wsdl获取的wsdl是否与axis2生成的wsdl相同。除非您在services.xml中更改了“useoriginalwsdl”的默认设置,否则这些wsdls可能会“看起来”不同。我从来没有必须手动执行java2wsdl才能让我的web服务正常工作...

所以基本上,在浏览器中打开服务网址,并在URL末尾添加?wsdl ...应该得到一个wsdl为了比较起见。

此外,请让客户端从服务器的wsdl生成存根,而不是由java2wsdl生成的存根(假设您最初使用的是来自java2wsdl的wsdl)。再次,我们从来没有必要将手动生成的wsdl传递给任何人...他们只是简单地从服务器上消耗动态生成的一个...

+0

我曾想过 - 但axis2名称空间是由java2wsdl自动生成的。我会想到,web方法被成功调用将意味着它不能成为命名空间的问题,但我会放弃它。 – Beardy 2009-06-16 14:15:41

0

您是否尝试过发送类似请求?

<?xml version='1.0' encoding='utf-8'?> 
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <soap:Body> 
    <request> 
     <GetGroups xmlns="http://stws/xsd"> 
     <serialcode>123456-654321</serialcode> 
     </GetGroups> 
    </request> 
    </soap:Body> 
</soap:Envelope> 

我所有的请求都具有实际的请求参数之前要求标签。

0

试试这个: 123456-654321

看跌的xmlns = “” 到参数标签。我有同样的问题,我不知道我可以修改什么,以便接收xmlnx的参数。

0

我有另一个修复程序。我最终发现,如果我没有让我的IDE(Netbeans 6.8)生成WSDL,那么Web服务工作。或者,如果我删除它,取消选中生成选项并重新部署,然后它工作。

比较一个NetBeans生成的WSDL到生成的一个服务器,我注意到以下区别:

  • 的xmlns:NS0 = “HTTP:/// XSD”
  • 目标命名空间是在wsdl的末尾:定义标签有一个尾随斜线用于选择组成WSDL的元素
  • NS0:message标签

删除所有这些问题并重新部署工作!

1

如果你有一个复杂的属性,这是你如何能做到这一点

之前

  <xs:complexType name="getMyMenu"> 
       <xs:sequence> 
        <xs:element minOccurs="0" name="number" nillable="true" type="xs:string"/> 
        <xs:element minOccurs="0" name="var2" nillable="true" type="xs:string"/> 
        <xs:element minOccurs="0" name="var3" nillable="true" type="xs:string"/> 
        <xs:element minOccurs="0" name="var4" nillable="true" type="xs:string"/> 
       </xs:sequence> 
      </xs:complexType> 

<xs:element name="getMyMenu"> 
      <xs:complexType> 
       <xs:sequence> 
        <xs:element minOccurs="0" name="number" nillable="true" type="xs:string"/> 
        <xs:element minOccurs="0" name="var2" nillable="true" type="xs:string"/> 
        <xs:element minOccurs="0" name="var3" nillable="true" type="xs:string"/> 
        <xs:element minOccurs="0" name="var4" nillable="true" type="xs:string"/> 
       </xs:sequence> 
      </xs:complexType> 
     </xs:element> 

后再改变这一

<wsdl:message name="getMyMenuRequest"> 
    <wsdl:part name="parameters" type="ns0:getUssdMenu"/> 
</wsdl:message> 

<wsdl:message name="getMyMenuRequest"> 
    <wsdl:part name="parameters" type="ns:getUssdMenu"/> 
</wsdl:message> 

这应该是它!它为我做了......