Axis2는 SOAP 요청이 올바르게 전송 되더라도 항상 NULL 매개 변수를 수신합니까?
-
05-07-2019 - |
문제
업데이트 : 지금이 문제를 해결했습니다. 수정에 대한 정보는 하단으로 스크롤하십시오.
안녕하세요 여러분,
axis2 / tomcat / apache 서버에서 호스팅 된 Java로 작성된 웹 서비스가 있습니다. 내 클라이언트 소프트웨어는 C#로 작성되었습니다.
Java2WSDL이 WSDL 파일을 생성하는 방식에 몇 가지 짜증을 낸 문제가 있었는데, 이는 일찍 몇 번의 두통을 일으켰지만이 문제로 인해 완전히 혼란 스러웠습니다.
기본적으로 클라이언트가 웹 서비스를 잘보고 매개 변수와 함께 완벽하게 유효한 비누 요청을 보냅니다.
서버에서 올바른 웹 메소드가 실행되지만 매개 변수는 모두 null입니다. 내 웹 서비스는 이것을 감지하고 클라이언트가 완벽하게 수신하고 이해하는 응답을 구축합니다.
내 직감은 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 파일은 유일한 매개 변수가 문자열이나 정수와 같은 단순한 유형 인 경우에도 웹 요청 및 매개 변수에 대한 복잡한 요소 유형을 만듭니다. 내가 한 일은 파라미터에 대한 올바른 간단한 타입 태그 (예 : '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>
분명히 그것은 당신의 매개 변수가 실제로 무엇인지에 따라 다릅니다. 제 경우에는 문자열 및 정수와 같은 표준 간단한 유형입니다. 둘 이상의 매개 변수를 전달하는 경우 자동 생성 요소를 유지하여 유형 속성을 'xs : 문자열'또는 그 특성의 무언가를 포함하지 않고 간단한 유형을 지칭하는지 확인해야 할 수도 있습니다. .
사과는 이것에 대해 더 명확하게 할 수는 없지만 앞서 말했듯이 이것이 왜 작동하는지 모르겠습니다.
마지막 한 가지 : 요청 태그에서 '요소'참조 속성을 제거하면 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을 사용하면이 두 네임 스페이스는 동일합니다.
<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을 수행 할 필요가 없었습니다 ...
따라서 기본적으로 브라우저에서 서비스 URL을 누르고 URL의 끝에서? WSDL에서 태클을 밟으십시오 ... 비교를 위해 WSDL을 가져와야합니다.
또한 클라이언트가 JAVA2WSDL에 의해 생성 된 서버 대신 서버의 WSDL에서 스터브를 생성하도록하십시오 (원래 Java2WSDL에서 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를 whitout 매개 변수를 수신하기 위해 무엇을 수정할 수 있는지 모르겠습니다.
또 다른 수정 사항이 있습니다. 결국 IDE (NetBeans 6.8)가 WSDL을 생성하지 않으면 웹 서비스가 작동한다는 것을 발견했습니다. 또는 삭제 한 경우 Generate 옵션을 풀고 재배치 한 다음 작동했습니다.
WSDL을 생성 한 NetBeans를 생성 한 사람과 비교하여 다음과 같은 차이점을 발견했습니다.
- xmlns : ns0 = "http : // xsd"
- WSDL의 끝에있는 대상 네임 스페이스 : 정의 태그는 후행 슬래시가 있습니다.
- NS0은 WSDL : 메시지 태그를 구성하는 요소를 선택하는 데 사용됩니다.
이 모든 것을 제거하고 재배치했습니다!