يتلقى Axis2 دائمًا معلمات فارغة حتى إذا تم إرسال طلب SOAP بشكل صحيح؟

StackOverflow https://stackoverflow.com/questions/1000578

سؤال

تحديث:لقد قمت بحل هذه المشكلة الآن - يرجى التمرير إلى الأسفل للحصول على معلومات حول الإصلاح

مرحبا الرجال،

لدي خدمة ويب مكتوبة بلغة Java، ومستضافة على خادم Axis2/Tomcat/Apache.برنامج العميل الخاص بي مكتوب بلغة C#.

لقد واجهت بعض المشاكل المزعجة مع الطريقة التي ينشئ بها java2wsdl ملف wsdl، الأمر الذي سبب لي بعض الصداع في وقت مبكر، ولكن مع هذه المشكلة أشعر بالحيرة تمامًا.

ما يحدث أساسًا هو أن العميل يرى خدمة الويب جيدة، ويرسل طلب SOAP صالحًا تمامًا (أو على الأقل يبدو صالحًا بالنسبة لي) مع المعلمات.

على الخادم، يتم تنفيذ طريقة الويب الصحيحة، ولكن المعلمات كلها فارغة.تكتشف خدمة الويب الخاصة بي ذلك وتقوم بإعداد استجابة يتلقاها العميل ويفهمها جيدًا.

حدسي هو أن 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>

هل لدى أي شخص أي فكرة عما يمكن أن يحدث بشكل خاطئ؟

لا يمكن إرسال رسالة الخطأ في الاستجابة إلا عندما تكون معلمة الرمز التسلسلي في الطلب فارغة/فارغة، لذلك أعتقد أن هناك خطأ ما في كيفية قراءة Axis2 للمعلمات الخاصة بي.

أي مساعدة هي محل تقدير كبير.

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

كيف يمكن اصلاح هذا:

هذا ردًا على طلب Aldo للحصول على مزيد من المعلومات حول كيفية حل هذه المشكلة.

لست متأكدًا من سبب نجاح هذا الإصلاح - ربما يكون مجرد خطأ في Axis2 أو شيء من هذا القبيل.وفي كلتا الحالتين، YMMV لأنني لا أعرف ما إذا كان سبب المشكلة هو الإعداد الخاص بي أو أي شيء آخر.كل ما يمكنني قوله هو أنه من خلال القيام بما يلي، بدأ كل شيء يعمل.

على أي حال، يقوم ملف WSDL الذي تم إنشاؤه تلقائيًا بإنشاء أنواع عناصر معقدة لطلبات الويب ومعلماتها، حتى عندما تكون المعلمات الوحيدة عبارة عن أنواع بسيطة مثل السلاسل أو الأعداد الصحيحة.ما فعلته هو مراجعة وإنشاء علامات النوع البسيط الصحيحة للمعلمات (مثل "الرمز التسلسلي" أو "سلسلة التاريخ")، ثم استبدال المراجع إلى الأنواع المعقدة في مكان آخر في ملف 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>

من الواضح أن ذلك يعتمد على ماهية المعلمات الخاصة بك بالفعل.في حالتي، فهي جميعها أنواع بسيطة قياسية مثل السلاسل والأعداد الصحيحة.إذا كنت تقوم بتمرير أكثر من معلمة واحدة، فقد تحتاج إلى التجول من خلال الاحتفاظ بالعناصر التي تم إنشاؤها تلقائيًا ولكن مع التأكد من أن العنصر يشير إلى أنواع بسيطة بدلاً من تضمين سمة النوع كـ "xs:string" أو شيء من هذا القبيل. .

أعتذر، لا أستطيع أن أكون أكثر وضوحًا بشأن هذا، ولكن كما قلت سابقًا - لا أعرف سبب نجاح هذا الأمر.

شيء أخير:عن طريق إزالة السمة المرجعية "العنصر" في علامات الطلب - قد تتلقى تحذيرًا محللًا في سجلات 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".مع كل WSDL التي تم إنشاؤها بواسطة Axis2، فإن مساحتي الأسماء هاتين متماثلتان.

<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 الذي حصلت عليه من java2wsdl هو نفسه الذي تم إنشاؤه بواسطة axis2.ما لم تقم بتغيير الإعداد الافتراضي لـ "useoriginalwsdl" في ملف Services.xml الخاص بك، فقد "تبدو" wsdls هذه مختلفة.لم أضطر أبدًا إلى إجراء Java2wsdl يدويًا حتى تعمل خدمة الويب الخاصة بي بشكل صحيح ...

لذا، بشكل أساسي، اضغط على عنوان URL الخاص بالخدمة في المتصفح ثم أدخل على ?wsdl في نهاية عنوان url... يجب أن تحصل على wsdl من أجل المقارنة.

أيضًا، اطلب من عميلك إنشاء بذرة من wsdl الخاص بالخادم بدلاً من تلك التي تم إنشاؤها بواسطة java2wsdl (بافتراض أنك استخدمت wsdl في الأصل من java2wsdl).مرة أخرى، لم نضطر أبدًا إلى تمرير 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، فإن خدمة الويب تعمل.وبدلاً من ذلك، إذا قمت بحذفه، فقم بإلغاء تحديد خيار الإنشاء وأعد نشره ثم يعمل.

بمقارنة WSDL الذي تم إنشاؤه بواسطة Netbeans بخادم تم إنشاؤه، لاحظت الاختلافات التالية:

  • xmlns:ns0 = "http:///xsd"
  • مساحة الاسم المستهدفة في نهاية علامة wsdl:definitions تحتوي على شرطة مائلة زائدة
  • يستخدم ns0 لاختيار العناصر التي تشكل علامة wsdl:message

لقد نجحت إزالة كل هذه الأشياء وإعادة النشر!

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top