3

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

我在 java2wsdl 生成 wsdl 文件的方式上遇到了一些恼人的问题,这在早期确实让我有些头疼,但是对于这个问题,我完全被难住了。

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

在服务器上,执行了正确的 web 方法,但参数全部为空。我的 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 请求及其参数创建复杂元素类型,即使唯一的参数是简单类型,例如字符串或整数。我所做的是检查并为参数创建正确的简单类型标记(例如“序列码”或“日期字符串”),然后将 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>

基本上你应该做的是丢弃自动生成的参数并创建简单类型。然后修改“请求”标签以使用“类型”而不是“元素”,并使用新创建的简单类型。

修改/固定 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' 或类似性质的东西.

抱歉,我对此不能说得更清楚,但正如我之前所说 - 我不知道为什么会这样。

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

4

6 回答 6

1

我通过查看我的 WSDL 文件解决了这个问题,并尽可能将元素分解为它们的简单类型对应物并相应地更新 XML 元素之间的引用。

我不确定为什么会这样,但无论如何它已经解决了我的问题。

于 2009-06-29T13:00:51.357 回答
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>

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

于 2010-11-04T08:06:09.457 回答
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 生成的相同。除非您在 services.xml 中更改了“useoriginalwsdl”的默认设置,否则这些 wsdl 可能“看起来”不同。我从来不需要手动执行 java2wsdl 来让我的 web 服务正常运行......

所以基本上,在浏览器中点击您的服务 URL 并在 url 末尾添加 ?wsdl ...您应该获得一个 wsdl 以进行比较。

此外,让您的客户端从服务器的 wsdl 生成存根,而不是由 java2wsdl 生成的存根(假设您最初使用的是 java2wsdl 中的 wsdl)。同样,我们不必将手动生成的 wsdl 传递给任何人……他们只是简单地使用了从服务器动态生成的……

于 2009-06-16T13:54:38.337 回答
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>

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

于 2009-06-26T13:20:00.487 回答
0

试试这个:123456-654321

将 xmlns="" 放入参数标签中。我有同样的问题,我不知道我可以修改什么来接收没有 xmlnx 的参数。

于 2009-08-24T15:34:11.347 回答
0

我有另一个修复。我最终发现,如果我不让我的 IDE (Netbeans 6.8) 生成 WSDL,那么 Web 服务就会起作用。或者,如果我删除它,取消选中生成选项并重新部署,那么它就可以工作了。

将 Netbeans 生成的 WSDL 与服务器生成的 WSDL 进行比较,我注意到以下差异:

  • xmlns:ns0="http:///xsd"
  • wsdl:definitions 标记末尾的目标命名空间有一个斜杠
  • ns0 用于选择组成 wsdl:message 标记的元素

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

于 2010-03-04T00:36:58.890 回答