2011-09-15 15 views
8

Pracuję na serwerze aplikacji Java 6, który ma usługę internetową do odbierania komunikatów SOAP zawierających wiadomość HL7. Aplikacja Java działa na Glassfish 3.1. Klient to aplikacja C# opracowana przez inną firmę (działająca w środowisku Microsoft .net 4.0) i wysyłająca te komunikaty SOAP na serwer Java.Metoda usługi WWW Java otrzymująca zerowy argument z klienta C#

Moim początkowym problemem było to, że klient nie mógł przeanalizować pliku WSDL wygenerowanego przez serwer. Od tego czasu rozwiązałem ten problem, implementując mój własny niestandardowy WSDL i odpowiednio go dostosowując. Pozwoliło to klientowi na przeanalizowanie pliku WSDL i wysłanie komunikatów SOAP do mojej aplikacji serwera Java.

Jednak za każdym razem, gdy wiadomość jest odbierana po stronie serwera, parametr (o nazwie "putXML") otrzymuje wartość null.

GlassFish dziennika serwera pokazuje następujący po odebraniu wiadomości:

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

Oto zwyczaj WSDL, że stworzył i związane z moim SOAP usługi internetowej:

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

i tu jest serwis WWW 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 
    } 
} 

Czy coś jest nie tak?

Co mogę zrobić, aby naprawić usługę WWW Java, aby prawidłowo otrzymała wartość inną niż null?

Czy to jest problem z klientem? Jeśli tak, czy powinienem stworzyć coś w rodzaju przechwytywacza?

Aktualizacja

Dzisiaj próbowałem tworząc szybki C# klienta, który używa mojego SOAP Java usługę internetową. Poniżej znajduje się kod:

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

Kiedy uruchomić tego klienta, otrzymuję taką samą wartość null w parametrze gdy spodziewałem się zobaczyć ciąg Test. Ponadto oczekuję, że result zawiera ciąg odpowiedzi, ale również zwraca wartość null.

Pamiętaj, że nie mogę zmodyfikować aplikacji klienckiej C# innej firmy. Czy jest coś, co mogę zrobić na końcu Java?

Aktualizacja 2

Niedawno dodane klasę łańcucha obsługi, która jest przechwytywanie i rejestrowanie surowych komunikatów SOAP. Wiadomość wysyłana przez klienta wygląda następująco:

<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

Wydaje się prawdopodobne, że serwer odbiera zerowy, ponieważ klient jest w tym parametru w żądaniu. – DwB

+0

@DwB Nie jestem pewien co masz na myśli. Czy mógłbyś rozwinąć? –

+0

Język źródłowy ma zerowy wpływ na wywołanie usługi internetowej. Jeśli usługa wywołanie parametru ma wartość null na serwerze, jest to spowodowane tym, że został wysłany jako klient null. – DwB

Odpowiedz

5

Po uzyskaniu wskazówek we właściwym kierunku przez @dlawrence, udało mi się rozwiązać mój problem. Jak wspomniałem w pytaniu, nadal potrzebowałem użyć niestandardowego wbudowanego wsdl.Aby rozwiązać problem, wystarczy wprowadzić kilka zmian we kodzie wsdl i Java.

Oto diff reprezentujący moje zmiany w 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> 

Zasadniczo był to trzyczęściowa fix ...
1). Musiałem usunąć atrybut elementFormDefault="qualified" ze znacznika <s:schema>.
2). Następnie musiałem dodać atrybut form="qualified" do mojego tagu <s:element name="putXML" ...>.
3). Na koniec, musiałem upewnić się, że mam atrybut soapAction="http://MyProject.MyPackage/putHL7Data" na moim tagu <soap:operation>.

Oto diff reprezentujący moje zmiany do sposobu internetowej 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 
    } 
} 

Jak widać, wszystko, co musiałem zrobić, to dodać atrybut targetNamespace do mojego @WebParam.

3

Czy próbowałeś usunąć atrybut @WebParam? Nie powinno to być wymagane, ponieważ nie ma tu żadnych dwuznaczności z twoją usługą sieciową i możliwe, że musisz ustawić przestrzeń docelową, aby mogła poprawnie znaleźć atrybut.

+1

Próbowałem usunąć "@WebParam", ale nie było efektu. Gdzie powinien iść "targetNamespace"? Wewnątrz definicji "@WebParam"? –

+0

Tak, powinien to być atrybut @WebParam. – dlawrence

+0

Dzięki za wskazówkę! Udało mi się wymyślić, jak dostosować mój niestandardowy klucz wsdl, widząc, co robi "targetNamespace" w wygenerowanych plikach wsdl. Wkrótce opublikuję własną odpowiedź wyjaśniającą, co zrobiłem, aby rozwiązać mój problem. –

2

Mam tę samą wiadomość w mojej konsoli glassfish. W moim projekcie android z funkcją ksoap zmieniłem następujący kod:

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

.... to działa ...);

klasy I generowane z http://www.wsdl2code.com

Powiązane problemy