2012-09-03 519 views
9

我的Web服務無法處理時,客戶端調用Web服務我的客戶的請求,而不會傳遞前綴,在SOAP體,如下所示:的WebService不能處理沒有命名空間前綴的SOAP Body要求

<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> 

錯誤是與GetPatientResultsRequest等對應的Java對象爲空。

看起來好像當Body中沒有前綴時,反序列化不會正常發生。我的Web服務能夠只響應時,SOAP機身擁有像

前綴
<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> 

任何人都可以讓我知道該怎麼做,這樣我的web服務可以採取各種SOAP請求(即有和沒有前綴身體)?

我使用JAX-WS(SOAP 1.1)

+0

你使用什麼客戶端? jaxws? – Cris

+1

你的兩個例子是不同的。在第一種情況下,命名空間位於'GetPatientResultsRequest'和'PatientIdentification','Period','From'和'To'元素上。在第二個例子中,它只在'GetPatientResultsRequest'元素上。 –

+0

我面臨同樣的問題。請告訴我,如果你能解決你的這個問題... –

回答

8

Web服務定義,你必須爲了把它遵循合同。您發佈的示例中只有一條消息與該合同相匹配,以便其中一個可以正常工作,另一個不會。

在您的第一封郵件中,您定義了一個默認名稱空間(因爲包裝中的xmlns屬性),並且所有未聲明並且沒有前綴的元素都位於相同的名稱空間中,因爲它們從父項繼承。

在第二條消息中,您有一個明確的前綴聲明,只有包裝器位於該名稱空間中,其他元素不在名稱空間中,並且不會從父級繼承默認值(因爲缺少xmlns屬性)。

正如我在開始時所說的,Web服務定義了一個合約。 修改客戶端發送正確的消息而不是將服務更改爲接受來自客戶端的錯誤消息更有意義。

要控制的元素,你需要使用的JAX-WS註釋Web服務和客戶端的的targetNamespace值的命名空間。

下面是一個示例,用於在更改目標名稱空間時查看代碼和消息格式的差異。我將使用這個基本的WSDL:

<?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> 

這定義像消息:

<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> 

和:

<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> 

見的包裝命名空間前綴?這是因爲這些元素是在http://tempuri.org命名空間中聲明的,而其他元素不是,也不在命名空間中。

甚至可以從命名空間中刪除所有元素。剝去WSDL目標命名空間,讓它看起來像這樣:

<?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將對應於類似的消息:

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

和:

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

沒有前綴這個案例。

現在雙方的WSDL使用wsimport.exe,你會看到我是在開始談論目標命名空間,即從這樣的變化:

@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); 
} 

這樣:

@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); 
} 

控制targetNamespace,你將控制消息的外觀。

相關問題