2011-09-15 71 views
8

我正在研究一個具有Web服務的Java 6應用程序服務器,該服務用於接收包含HL7消息的SOAP消息。 Java應用程序在Glassfish 3.1上運行。客戶端是第三方開發的C#應用​​程序(它運行在Microsoft .NET 4.0框架上),它將這些SOAP消息發送到Java服務器。從C#客戶端接收null參數的Java Web服務方法

我最初的問題是客戶端無法解析服務器生成的WSDL。我已經通過實現我自己的自定義WSDL並相應地調整它來解決這個問題。這允許客戶端解析WSDL並將SOAP消息發送到我的Java服務器應用程序。

但是,每次在服務器端接收到消息時,該參數(名爲「putXML」)正在接收值null

GlassFish服務器日誌顯示接收到的消息時,以下幾點:

Received WS-I BP non-conformant Unquoted SoapAction HTTP header: http://MyProject.MyPackage/putHL7Data 
Received Message: null 

這裏是我創建並與我的SOAP的Web服務相關聯的自定義WSDL:

<?xml version="1.0" encoding="utf-8"?> 
<wsdl:definitions 
     targetNamespace="http://MyProject.MyPackage/" 
     xmlns="http://schemas.xmlsoap.org/wsdl/" 
     xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" 
     xmlns:s="http://www.w3.org/2001/XMLSchema" 
     xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" 
     xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" 
     xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" 
     xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/" 
     xmlns:tns="http://MyProject.MyPackage/" 
     xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" 
     xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" 
     xmlns:wsp="http://www.w3.org/ns/ws-policy" 
     xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" 
     xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <wsdl:types> 
     <s:schema elementFormDefault="qualified" targetNamespace="http://MyProject.MyPackage/"> 
     <s:element name="putHL7Data"> 
      <s:complexType> 
       <s:sequence> 
        <s:element name="putXML" type="s:string" minOccurs="0" maxOccurs="1"/> 
       </s:sequence> 
      </s:complexType> 
     </s:element> 
     <s:element name="putHL7DataResponse"> 
      <s:complexType> 
       <s:sequence> 
        <s:element name="return" type="s:string" minOccurs="0" maxOccurs="1"/> 
       </s:sequence> 
      </s:complexType> 
     </s:element> 
     </s:schema> 
    </wsdl:types> 
    <wsdl:message name="putHL7DataSoapIn"> 
     <wsdl:part name="parameters" element="tns:putHL7Data"/> 
    </wsdl:message> 
    <wsdl:message name="putHL7DataSoapOut"> 
     <wsdl:part name="parameters" element="tns:putHL7DataResponse"/> 
    </wsdl:message> 
    <wsdl:portType name="MyHandlerSoap"> 
     <wsdl:operation name="putHL7Data"> 
     <wsdl:input message="tns:putHL7DataSoapIn"/> 
     <wsdl:output message="tns:putHL7DataSoapOut"/> 
     </wsdl:operation> 
    </wsdl:portType> 
    <wsdl:binding name="MyHandlerSoap" type="tns:MyHandlerSoap"> 
     <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/> 
     <wsdl:operation name="putHL7Data"> 
     <wsdl:input> 
      <soap:body use="literal"/> 
     </wsdl:input> 
     <wsdl:output> 
      <soap:body use="literal"/> 
     </wsdl:output> 
     </wsdl:operation> 
    </wsdl:binding> 
    <wsdl:service name="MyHandler"> 
     <wsdl:port name="MyHandlerPort" binding="tns:MyHandlerSoap"> 
     <soap:address location="REPLACE_WITH_ACTUAL_URL"/> 
     </wsdl:port> 
    </wsdl:service> 
</wsdl:definitions> 

這裏是Java網絡服務:

@WebService(serviceName = "MyHandler", wsdlLocation = "WEB-INF/wsdl/MyHandler.wsdl") 
public class MyHandler { 
    @WebMethod(operationName = "putHL7Data") 
    public String putHL7Data(@WebParam(name = "putXML") String xml) { 
     // Handle message 
    } 
} 

有什麼我做錯了嗎?

我能做些什麼來修復Java Web服務,以便正確接收非空值?

這是客戶的問題嗎?如果是這樣,我是否需要創建某種攔截器?

更新

今天我嘗試創建它使用我的Java SOAP Web服務的快速C#的客戶端。下面是代碼:

namespace TestSoap 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      ServiceReference1.MyHandlerSoapClient ws = new ServiceReference1.MyHandlerSoapClient(); 
      string result = ws.putHL7Data("Test");  
      Console.WriteLine("Response: " + result); 
      Console.ReadLine(); 
     } 
    } 
} 

當我運行這個客戶,我在的時候,我期待看到Test字符串參數接收相同null值。此外,我期望result包含一個響應字符串,但它也返回一個null值。

請記住,我無法修改第三方C#客戶端應用程序。在Java端有什麼我可以做的嗎?

更新2

我最近添加其被捕獲和記錄的原始SOAP消息的處理程序鏈類別。由客戶端發送的消息如下所示:

<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:Header/> 
    <soap:Body> 
    <putHL7Data xmlns="http://MyProject.MyPackage/"> 
     <putXML>... Encoded XML Here ...</putXML> 
    </putHL7Data> 
    </soap:Body> 
</soap:Envelope> 
+0

這很可能是因爲客戶端被包括在請求中的參數的服務器接收空生成的類。 – DwB

+0

@DwB我不確定你的意思。你能詳細說明一下嗎? –

+0

源語言對Web服務調用沒有影響。如果服務調用參數在服務器中爲空,那是因爲它是從客戶端發送爲空的。 – DwB

回答

5

通過@dlawrence指出正確的方向後,我能解決我的問題。正如我在問題中提到的,我仍然需要使用定製的wsdl。我只需要對wsdl和Java代碼進行一些更改以解決問題。

這裏是代表我的更改WSDL一個差異:

--- /tmp/a 2011-09-19 15:05:21.132065003 -0400 
+++ /tmp/b 2011-09-19 14:41:28.302064999 -0400 
@@ -15,11 +15,11 @@ 
     xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" 
     xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <wsdl:types> 
-  <s:schema elementFormDefault="qualified" targetNamespace="http://MyProject.MyPackage/"> 
+  <s:schema targetNamespace="http://MyProject.MyPackage/">   
      <s:element name="putHL7Data"> 
      <s:complexType> 
       <s:sequence> 
-     <s:element name="putXML" type="s:string" minOccurs="0" maxOccurs="1"/> 
+     <s:element name="putXML" type="s:string" form="qualified" minOccurs="0" maxOccurs="1"/> 
       </s:sequence> 
      </s:complexType> 
      </s:element> 
@@ -47,6 +47,6 @@ 
    <wsdl:binding name="MyHandlerSoap" type="tns:MyHandlerSoap"> 
     <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/> 
     <wsdl:operation name="putHL7Data"> 
-   <soap:operation soapAction="" style="document"/> 
+   <soap:operation soapAction="http://MyProject.MyPackage/putHL7Data" style="document"/> 
      <wsdl:input> 
      <soap:body use="literal"/> 
      </wsdl:input> 

基本上這是一個三部分的修復...
1)。我需要從<s:schema>標記中刪除elementFormDefault="qualified"屬性。 2)。然後,我必須在我的<s:element name="putXML" ...>標記上添加屬性form="qualified"。 3)。最後,我需要確保我的<soap:operation>標籤上有屬性soapAction="http://MyProject.MyPackage/putHL7Data"

這裏是代表我改變對Java Web方法的差異:

--- /tmp/a 2011-09-19 14:57:49.582065002 -0400 
+++ /tmp/b 2011-09-19 15:00:06.942065007 -0400 
@@ -1,7 +1,7 @@ 
@WebService(serviceName = "MyHandler", wsdlLocation = "WEB-INF/wsdl/MyHandler.wsdl") 
public class MyHandler { 
    @WebMethod(operationName = "putHL7Data") 
- public String putHL7Data(@WebParam(name = "putXML") String xml) { 
+ public String putHL7Data(@WebParam(name = "putXML", targetNamespace="http://MyProject.MyPackage/") String xml) { 
     // Handle message 
    } 
} 

正如你所看到的,我所要做的就是在targetNamespace屬性添加到我@WebParam

3

您是否嘗試刪除@WebParam屬性?它不應該被要求,因爲在這裏你的web服務沒有歧義,並且你可能需要設置targetNamespace,以便它能夠正確地找到屬性。

+1

我試圖刪除「@WebParam」,但沒有效果。 「targetNamespace」會去哪裏?在「@WebParam」定義裏面? –

+0

是的,它應該是@WebParam的一個屬性。 – dlawrence

+0

感謝您的提示!我能夠弄清楚如何通過添加「targetNamespace」對生成的wsdl做什麼來調整我的自定義wsdl。我會盡快發佈自己的答案,解釋我爲解決問題所做的工作。 –

2

我在我的glassfish控制檯中有相同的消息。在我與KSOAP功能的Android項目我改變了下面的代碼:

soapEnvelope.setOutputSoapObject(soapReq); 
HttpTransportSE httpTransport = new HttpTransportSE(url,timeOut); 
try{ 

     if (headers!=null){ 
      // original code // my headers are null 
      httpTransport.call("http://service.iswitch.com/", soapEnvelope,headers); 
     }else{ 
      httpTransport.call("\"http://service.iswitch.com/"\", soapEnvelope); 
     } 
     SoapObject result=(SoapObject)soapEnvelope.bodyIn; 
     if (result.hasProperty("moveResult")) 
     { 

.... 它的工作原理...);

i相http://www.wsdl2code.com

相關問題