更新:我现在已经解决了这个问题 - 请滚动到底部以获取有关修复的信息
大家好,
我有一个用Java编写的Web服务,托管在Axis2 / Tomcat / Apache服务器上。我的客户端软件是用C#编写的。
我对java2wsdl生成wsdl文件的方式有一些恼人的问题,这确实让我在早期遇到了一些麻烦,但有了这个问题,我完全被难倒了。
基本上发生的事情是客户端看到Web服务正常,并发送一个完全有效的(或者至少看起来对我来说有效)带有参数的SOAP请求。
在服务器上,执行正确的Web方法,但参数都为null。我的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参数为空/ null时发送,所以我猜测Axis2读取参数的方式有问题。
非常感谢任何帮助。
=============================================== =============
如何修复此问题:
这是对Aldo要求提供有关我如何解决此问题的更多信息的回应。
我不确定为什么这个修复工作 - 也许它只是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 :(得分:1)
我通过浏览我的WSDL文件解决了这个问题,并且尽可能将元素分解为简单类型的对应物并相应地更新XML元素之间的引用。
我不确定为什么会这样,但无论如何它已经解决了我的问题。
答案 1 :(得分:1)
如果你有一个复杂的属性,你可以这样做
之前
<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>
在
<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>
然后改变这个
<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>
那应该是它!它为我做了......
答案 2 :(得分:0)
这只是一种预感,但也许你有一个命名空间问题。如果您专注于wsdl的这一部分,请注意您的参数具有元素的“ns0”命名空间,但在稍后定义的操作中,看起来您正在使用“axis2”命名空间。使用我的所有Axis2生成的WSDL,这两个名称空间是相同的。
<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并在url的末尾添加?wsdl ...你应该得到一个wsdl用于比较。
此外,让您的客户端从服务器的wsdl生成存根,而不是由java2wsdl生成的存根(假设您最初使用的是java2wsdl中的wsdl)。同样,我们永远不必将手动生成的wsdl传递给任何人......他们只是简单地从服务器中消耗了动态生成的一个...
答案 3 :(得分: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>
我的所有请求在实际请求参数之前都有请求标记。
答案 4 :(得分:0)
试试这个: 123456-654321
将xmlns =“”放入参数标记中。我有同样的问题,我不知道我可以修改什么,以便接收参数whitout xmlnx。
答案 5 :(得分:0)
我有另一个修复。我最终发现,如果我不让我的IDE(Netbeans 6.8)生成WSDL,那么Web服务就可以了。或者,如果我删除了它,则取消选中generate选项并重新部署然后它就可以了。
将Netbeans生成的WSDL与生成的服务器进行比较,我注意到以下差异:
删除所有这些并重新部署工作!