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.
khách hàng nào bạn sử dụng? jaxws? – Cris
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'. –
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 ... –