SOAPリクエストが正しく送信された場合でも、Axis2は常にnullパラメータを受け取りますか?
-
05-07-2019 - |
質問
アップデート:この問題は現在解決しました - 修正に関する情報については一番下までスクロールしてください
こんにちは、みんな、
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>
何が問題なのかわかる人はいますか?
応答のエラー メッセージは、リクエストのシリアルコード パラメーターが空または 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>
基本的にやるべきことは、自動生成されたパラメータを破棄し、単純な型を作成することです。次に、「要素」ではなく「タイプ」を使用するように「リクエスト」タグを変更し、新しく作成した単純型を使用します。
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 ログにパーサー警告が表示される場合があります。今のところ問題は起きていませんが、万が一問題が発生した場合に備えて注意が必要です。
解決
私は、WSDL ファイルを調べ、可能な限り要素を対応する単純なタイプに分割し、それに応じて XML 要素間の参照を更新することで、この問題を解決しました。
なぜこれが機能するのかはわかりませんが、とにかく私の問題は解決しました。
他のヒント
複雑な属性がある場合は、次のようにすることができます
前に
<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>
それもそのはずです!それは私のためにそれをしてくれました....
これは単なる予感ですが、名前空間に問題がある可能性があります。wsdl のこの部分に注目すると、パラメータには要素の「ns0」名前空間がありますが、後で定義する操作では「axis2」名前空間を使用しているように見えることに注意してください。Axis2 で生成されたすべての WSDL では、これら 2 つの名前空間は同じです。
<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>
もう 1 つチェックできることは、java2wsdl から取得した wsdl が axis2 によって生成されたものと同じであることを確認することです。services.xml の「useoriginalwsdl」のデフォルト設定を変更していない限り、これらの wsdl は「見た目」が異なる可能性があります。Web サービスを正しく機能させるために java2wsdl を手動で実行する必要はありませんでした...
基本的には、ブラウザでサービス URL にアクセスし、URL の最後に ?wsdl を付け加えます。比較のために wsdl を取得する必要があります。
また、クライアントに、java2wsdl によって生成されたスタブではなく、サーバーの wsdl からスタブを生成させます (最初に java2wsdl の wsdl を使用したと仮定します)。繰り返しになりますが、手動で生成した wsdl を誰かに渡す必要はありませんでした。サーバーから動的に生成された wsdl を単に消費するだけでした...
このようなリクエストを送信してみましたか?
<?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>
私のすべてのリクエストには、 リクエスト 実際のリクエストパラメータの前にタグを追加します。
これを試して:123456-654321
パラメータタグにxmlns=""を入れます。私も同じ問題を抱えており、xmlnx なしでパラメーターを受け取るために何を変更できるかわかりません。
別の修正があります。最終的に、IDE (Netbeans 6.8) に WSDL を生成させなければ、Web サービスは機能することがわかりました。あるいは、それを削除し、生成オプションのチェックを外して再デプロイすると、機能しました。
Netbeans で生成された WSDL とサーバーで生成された WSDL を比較すると、次の違いがあることに気付きました。
- xmlns:ns0="http:///xsd"
- wsdl:settings タグの末尾のターゲット名前空間の末尾にスラッシュがあった
- ns0 は、wsdl:message タグを構成する要素を選択するために使用されます
これらをすべて削除して再デプロイするとうまくいきました。