2012-09-03 23 views
9

dịch vụ web của tôi không thể xử lý yêu cầu khách hàng của mình khi khách hàng đang kêu gọi các dịch vụ web mà không đi tiền tố trong cơ thể SOAP như sau:WebService không thể xử lý yêu cầu với SOAP Body không có một tiền tố namespace

<soap:Body> 
<GetPatientResultsRequest xmlns="http://urlA"> 
    <PatientIdentification> 
     <PersonCivilRegistrationIdentifier xmlns="http://UrlB"/> 
    </PatientIdentification> 
    <Period> 
    <From>2012-05-26</From> 
    <To>2012-06-26</To> 
    </Period> 
</GetPatientResultsRequest> 
</soap:Body> 

Lỗi là đối tượng Java tương ứng với GetPatientResultsRequest và các đối tượng khác là rỗng.

Dường như khi không có tiền tố trong Nội dung, quá trình deserialization không diễn ra đúng cách. dịch vụ web của tôi là khả năng đáp ứng chỉ khi cơ thể SOAP có một tiền tố như

<soap:Body> 
<m:GetPatientResultsRequest xmlns:m="http://urlA"> 
    <PatientIdentification> 
     <PersonCivilRegistrationIdentifier xmlns="http://UrlB"/> 
    </PatientIdentification> 
    <Period> 
    <From>2012-05-26</From> 
    <To>2012-06-26</To> 
    </Period> 
</m:GetPatientResultsRequest> 
</soap:Body> 

bất cứ ai có thể cho tôi biết phải làm gì để phục vụ web của tôi có thể mất các yêu cầu SOAP của tất cả các loại (tức là có và không có tiền tố trong Thân hình)?

Tôi đang sử dụng JAX-WS (SOAP 1.1) dịch vụ

+0

khách hàng nào bạn sử dụng? jaxws? – Cris

+1

Hai ví dụ của bạn là khác nhau. Trong trường hợp đầu tiên, thì không gian tên nằm trên các phần tử 'GetPatientResultsRequest' và' PatientIdentification', 'Period',' From' và 'To'. Trong ví dụ thứ hai, nó chỉ nằm trên phần tử 'GetPatientResultsRequest'. –

+0

Tôi đang đối mặt với cùng một vấn đề. Vui lòng cho tôi biết nếu bạn có thể giải quyết vấn đề này của bạn ... –

Trả lời

8

Một web định nghĩa một hợp đồng mà bạn phải tuân theo để gọi nó. Chỉ một thông điệp từ các ví dụ bạn đã đăng khớp với hợp đồng đó để một tác phẩm, cái kia thì không. Trong thông điệp đầu tiên của bạn, bạn đã xác định một không gian tên mặc định (vì thuộc tính xmlns trong trình bao bọc) và tất cả các phần tử của bạn không khai báo nó và không có tiền tố nằm trong cùng một không gian tên vì chúng kế thừa từ cha mẹ của chúng. . Trong thư thứ hai của bạn, bạn có khai báo tiền tố rõ ràng và chỉ có trình bao bọc trong các không gian tên đó, các phần tử khác không nằm trong vùng tên và không kế thừa một phần tử mặc định từ cha mẹ (vì thiếu thuộc tính xmlns).

Như tôi đã nói lúc đầu, dịch vụ web xác định hợp đồng. Điều này có ý nghĩa hơn khi sửa đổi các khách hàng để gửi tin nhắn chính xác thay vì thay đổi dịch vụ để chấp nhận các tin nhắn không chính xác từ máy khách.

Để kiểm soát không gian tên của các yếu tố của bạn, bạn cần phải sử dụng targetNamespace giá trị trên chú thích JAX-WS của dịch vụ web của bạn và khách hàng.

Dưới đây là ví dụ để thấy sự khác biệt về mã và định dạng tin nhắn khi bạn thay đổi không gian tên đích. Tôi sẽ sử dụng một WSDL cơ bản cho việc này:

<?xml version="1.0" encoding="utf-8"?> 
<wsdl:definitions 
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" 
xmlns:tns="http://tempuri.org" 
xmlns:xs="http://www.w3.org/2001/XMLSchema" 
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" 
targetNamespace="http://tempuri.org" 
name="CalculatorWS"> 
    <wsdl:types> 
    <xs:schema targetNamespace="http://tempuri.org"> 
     <xs:element name="add" type="tns:add" /> 
     <xs:element name="addInput" type="tns:addInput" /> 
     <xs:element name="addResponse" type="tns:addResponse" /> 
     <xs:element name="addOutput" type="tns:addOutput" /> 
     <xs:complexType name="add"> 
     <xs:sequence> 
      <xs:element name="addInput" type="tns:addInput" /> 
     </xs:sequence> 
     </xs:complexType> 
     <xs:complexType name="addInput"> 
     <xs:sequence> 
      <xs:element name="a" type="xs:int" /> 
      <xs:element name="b" type="xs:int" /> 
     </xs:sequence> 
     </xs:complexType> 
     <xs:complexType name="addResponse"> 
     <xs:sequence> 
      <xs:element name="addOutput" type="tns:addOutput" /> 
     </xs:sequence> 
     </xs:complexType> 
     <xs:complexType name="addOutput"> 
     <xs:sequence> 
      <xs:element name="result" type="xs:int" /> 
     </xs:sequence> 
     </xs:complexType> 
    </xs:schema> 
    </wsdl:types> 
    <wsdl:message name="add"> 
    <wsdl:part name="parameters" element="tns:add" /> 
    </wsdl:message> 
    <wsdl:message name="addResponse"> 
    <wsdl:part name="parameters" element="tns:addResponse" /> 
    </wsdl:message> 
    <wsdl:portType name="CalculatorWS"> 
    <wsdl:operation name="add"> 
     <wsdl:input message="tns:add" /> 
     <wsdl:output message="tns:addResponse" /> 
    </wsdl:operation> 
    </wsdl:portType> 
    <wsdl:binding name="CalculatorWSPortBinding" type="tns:CalculatorWS"> 
    <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document" /> 
    <wsdl:operation name="add"> 
     <soap:operation soapAction="http://tempuri.org/add" /> 
     <wsdl:input> 
     <soap:body use="literal" /> 
     </wsdl:input> 
     <wsdl:output> 
     <soap:body use="literal" /> 
     </wsdl:output> 
    </wsdl:operation> 
    </wsdl:binding> 
    <wsdl:service name="CalculatorWSService"> 
    <wsdl:port name="CalculatorWSPort" binding="tns:CalculatorWSPortBinding"> 
     <soap:address location="http://localhost:8080/WebServices/CalculatorWS" /> 
    </wsdl:port> 
    </wsdl:service> 
</wsdl:definitions> 

này định nghĩa các thông điệp như:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
     xmlns:tem="http://tempuri.org"> 
    <soapenv:Body> 
     <tem:add> 
     <addInput> 
      <a>?</a> 
      <b>?</b> 
     </addInput> 
     </tem:add> 
    </soapenv:Body> 
</soapenv:Envelope> 

và:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
     xmlns:tem="http://tempuri.org"> 
    <soapenv:Body> 
     <tem:addResponse> 
     <addOutput> 
      <result>?</result> 
     </addOutput> 
     </tem:addResponse> 
    </soapenv:Body> 
</soapenv:Envelope> 

Xem các tiền tố không gian tên trên giấy gói? Đó là bởi vì các phần tử được khai báo trong không gian tên http://tempuri.org trong khi các phần tử khác không và không nằm trong vùng tên.

Bạn thậm chí có thể xóa tất cả các phần tử khỏi không gian tên.Dải không gian tên mục tiêu từ WSDL và làm cho nó trông như thế này:

<?xml version="1.0" encoding="utf-8"?> 
<wsdl:definitions 
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" 
xmlns:xs="http://www.w3.org/2001/XMLSchema" 
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" 
name="CalculatorWS"> 
    <wsdl:types> 
    <xs:schema> 
     <xs:element name="add" type="add" /> 
     <xs:element name="addInput" type="addInput" /> 
     <xs:element name="addResponse" type="addResponse" /> 
     <xs:element name="addOutput" type="addOutput" /> 
     <xs:complexType name="add"> 
     <xs:sequence> 
      <xs:element name="addInput" type="addInput" /> 
     </xs:sequence> 
     </xs:complexType> 
     <xs:complexType name="addInput"> 
     <xs:sequence> 
      <xs:element name="a" type="xs:int" /> 
      <xs:element name="b" type="xs:int" /> 
     </xs:sequence> 
     </xs:complexType> 
     <xs:complexType name="addResponse"> 
     <xs:sequence> 
      <xs:element name="addOutput" type="addOutput" /> 
     </xs:sequence> 
     </xs:complexType> 
     <xs:complexType name="addOutput"> 
     <xs:sequence> 
      <xs:element name="result" type="xs:int" /> 
     </xs:sequence> 
     </xs:complexType> 
    </xs:schema> 
    </wsdl:types> 
    <wsdl:message name="add"> 
    <wsdl:part name="parameters" element="add" /> 
    </wsdl:message> 
    <wsdl:message name="addResponse"> 
    <wsdl:part name="parameters" element="addResponse" /> 
    </wsdl:message> 
    <wsdl:portType name="CalculatorWS"> 
    <wsdl:operation name="add"> 
     <wsdl:input message="add" /> 
     <wsdl:output message="addResponse" /> 
    </wsdl:operation> 
    </wsdl:portType> 
    <wsdl:binding name="CalculatorWSPortBinding" type="CalculatorWS"> 
    <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document" /> 
    <wsdl:operation name="add"> 
     <soap:operation soapAction="http://tempuri.org/add" /> 
     <wsdl:input> 
     <soap:body use="literal" /> 
     </wsdl:input> 
     <wsdl:output> 
     <soap:body use="literal" /> 
     </wsdl:output> 
    </wsdl:operation> 
    </wsdl:binding> 
    <wsdl:service name="CalculatorWSService"> 
    <wsdl:port name="CalculatorWSPort" binding="CalculatorWSPortBinding"> 
     <soap:address location="http://localhost:8080/WebServices/CalculatorWS" /> 
    </wsdl:port> 
    </wsdl:service> 
</wsdl:definitions> 

WSDL mới này sẽ tương ứng với thông điệp như:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> 
    <soapenv:Body> 
     <add> 
     <addInput> 
      <a>?</a> 
      <b>?</b> 
     </addInput> 
     </add> 
    </soapenv:Body> 
</soapenv:Envelope> 

và:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> 
    <soapenv:Body> 
     <addResponse> 
     <addOutput> 
      <result>?</result> 
     </addOutput> 
     </addResponse> 
    </soapenv:Body> 
</soapenv:Envelope> 

Không tiền tố trong trường hợp này.

Bây giờ sử dụng wsimport.exe trên cả WSDLs và bạn sẽ thấy những namespace mục tiêu tôi đã nói ngay từ đầu, cụ thể là một sự thay đổi từ này:

@WebService(name = "CalculatorWS", targetNamespace = "http://tempuri.org") 
public interface CalculatorWS { 
    @WebMethod(action = "http://tempuri.org/add") 
    @WebResult(name = "addOutput", targetNamespace = "") 
    @RequestWrapper(localName = "add", targetNamespace = "http://tempuri.org", className = "your.pack.age.Add") 
    @ResponseWrapper(localName = "addResponse", targetNamespace = "http://tempuri.org", className = "your.pack.age.AddResponse") 
    public AddOutput add(
     @WebParam(name = "addInput", targetNamespace = "") 
     AddInput addInput); 
} 

này:

@WebService(name = "CalculatorWS", targetNamespace = "") 
public interface CalculatorWS { 
    @WebMethod(action = "http://tempuri.org/add") 
    @WebResult(name = "addOutput", targetNamespace = "") 
    @RequestWrapper(localName = "add", targetNamespace = "", className = "your.pack.age.Add") 
    @ResponseWrapper(localName = "addResponse", targetNamespace = "", className = "your.pack.age.AddResponse") 
    public AddOutput add(
     @WebParam(name = "addInput", targetNamespace = "") 
     AddInput addInput); 
} 

Kiểm soát targetNamespace và bạn sẽ kiểm soát thông báo trông như thế nào.