2011-09-15 22 views
8

Tôi đang làm việc trên máy chủ ứng dụng Java 6 có dịch vụ web để nhận tin nhắn SOAP chứa thông điệp HL7. Ứng dụng Java chạy trên Glassfish 3.1. Máy khách là một ứng dụng C# do bên thứ ba phát triển (chạy trên khung công tác .net 4.0 của Microsoft) và nó đang gửi các thông báo SOAP này tới máy chủ Java.Phương thức dịch vụ web Java nhận đối số null từ C# client

Vấn đề ban đầu của tôi là khách hàng không thể phân tích cú pháp WSDL do máy chủ tạo. Tôi đã giải quyết điều đó bằng cách thực hiện WSDL tùy chỉnh của riêng mình và điều chỉnh nó cho phù hợp. Điều này cho phép máy khách phân tích cú pháp WSDL và gửi các thông báo SOAP đến ứng dụng máy chủ Java của tôi.

Tuy nhiên, mỗi khi nhận được thư ở phía máy chủ, thông số (có tên "putXML") đang nhận giá trị null.

Nhật ký máy chủ Glassfish cho thấy sau khi một thông điệp được nhận:

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

Đây là WSDL tùy chỉnh mà tôi tạo ra và gắn liền với dịch vụ web SOAP của tôi:

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

Và đây là dịch vụ web 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 
    } 
} 

Tôi có làm gì sai không?

Tôi có thể làm gì để sửa dịch vụ web Java để nó nhận đúng giá trị không null?

Đây có phải là vấn đề với khách hàng không? Nếu vậy, liệu tôi có cần tạo ra một loại máy đánh chặn nào đó không?

Cập nhật

Hôm nay tôi cố gắng tạo ra một cách nhanh chóng C# client trong đó sử dụng dịch vụ web SOAP Java của tôi. Dưới đây là các mã:

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

Khi tôi chạy khách hàng này, tôi nhận được cùng một giá trị null trong tham số khi tôi đang mong đợi để xem chuỗi Test. Ngoài ra, tôi mong đợi result để chứa chuỗi phản hồi nhưng nó cũng trả lại giá trị null.

Hãy nhớ rằng, tôi không thể sửa đổi ứng dụng khách C# của bên thứ ba. Tôi có thể làm gì ở đầu Java không?

Cập nhật 2

Gần đây tôi đã bổ sung thêm một lớp dây chuyền xử lý được chụp và đăng nhập các thông điệp SOAP thô. Thư được khách hàng gửi như sau:

<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

Dường như có khả năng là máy chủ đang nhận được null vì khách hàng là bao gồm các tham số trong yêu cầu. – DwB

+0

@DwB Tôi không chắc chắn ý của bạn là gì. Bạn có thể xây dựng? –

+0

Ngôn ngữ nguồn không ảnh hưởng đến cuộc gọi dịch vụ web. Nếu dịch vụ gọi một tham số là null trong máy chủ đó là bởi vì nó đã được gửi dưới dạng null từ máy khách. – DwB

Trả lời

5

Sau khi nhận được hướng đi đúng theo @dlawrence, tôi đã có thể giải quyết được vấn đề của mình. Như tôi đã đề cập trong câu hỏi, tôi vẫn cần sử dụng một wsdl được xây dựng tùy chỉnh.Tôi chỉ cần thực hiện một vài thay đổi đối với wsdl và mã Java để giải quyết vấn đề.

Dưới đây là một diff đại diện cho sự thay đổi của tôi vào 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> 

Về cơ bản đây là một sửa chữa ba phần ...
1). Tôi cần xóa thuộc tính elementFormDefault="qualified" khỏi thẻ <s:schema>.
2). Sau đó, tôi phải thêm thuộc tính form="qualified" vào thẻ <s:element name="putXML" ...> của mình.
3). Cuối cùng, tôi cần đảm bảo rằng tôi có thuộc tính soapAction="http://MyProject.MyPackage/putHL7Data" trên thẻ <soap:operation> của mình.

Dưới đây là một diff đại diện cho sự thay đổi của tôi với phương pháp web Java:

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

Như bạn thấy, tất cả tôi phải làm là thêm thuộc tính targetNamespace-@WebParam tôi.

3

Bạn đã thử xóa thuộc tính @WebParam chưa? Nó không nên được yêu cầu vì không có sự mơ hồ với dịch vụ web của bạn ở đây và có thể bạn cần phải đặt targetNamespace để nó tìm đúng thuộc tính.

+1

Tôi đã thử xóa "@WebParam" nhưng không có hiệu lực. "TargetNamespace" sẽ đi đâu? Bên trong định nghĩa "@WebParam"? –

+0

Có, nó phải là một thuộc tính của @WebParam. – dlawrence

+0

Cảm ơn lời khuyên của bạn! Tôi đã có thể tìm ra cách để tinh chỉnh wsdl tùy chỉnh của tôi bằng cách nhìn thấy những gì thêm "targetNamespace" không để tạo ra wsdl của. Tôi sẽ đăng câu trả lời của riêng mình sớm giải thích những gì tôi đã làm để giải quyết vấn đề của tôi. –

2

tôi có cùng một thông báo trong bảng điều khiển thủy tinh của mình. Trong dự án android của tôi với chức năng ksoap tôi đã thay đổi mã sau:

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")) 
     { 

.... nó hoạt động ...);

lớp tôi tạo ra với http://www.wsdl2code.com

Các vấn đề liên quan