2011-09-15 4 views
8

Sto lavorando su un server applicazioni Java 6 che dispone di un servizio Web per la ricezione di messaggi SOAP contenenti un messaggio HL7. L'applicazione Java viene eseguita su Glassfish 3.1. Il client è un'applicazione C# sviluppata da terzi (che gira sul framework Microsoft .net 4.0) e invia questi messaggi SOAP al server Java.Metodo del servizio Web Java che riceve argomento null dal client C#

Il mio problema iniziale era che il client non era in grado di analizzare il WSDL generato dal server. Da allora l'ho risolto implementando il mio WSDL personalizzato e ottimizzandolo di conseguenza. Ciò ha consentito al client di analizzare il WSDL e inviare messaggi SOAP alla mia applicazione server Java.

Tuttavia, ogni volta che viene ricevuto un messaggio sul lato server, il parametro (denominato "putXML") riceve un valore null.

Il log del server Glassfish mostra il seguente quando viene ricevuto un messaggio:

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

Ecco il WSDL personalizzato che ho creato e associato al mio SOAP servizio web:

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

Ed è qui il servizio 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 
    } 
} 

C'è qualcosa che sto facendo male?

Cosa posso fare per riparare il servizio Web Java in modo che riceva correttamente un valore non nullo?

Si tratta di un problema con il cliente? In tal caso, dovrei creare una specie di intercettore?

Aggiornamento

Oggi ho cercato di creare un client rapido C#, che usa il mio servizio Web Java SOAP. Di seguito è riportato il codice:

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

Quando eseguo questo client, ricevo lo stesso valore null nel parametro quando mi aspettavo di vedere la stringa Test. Inoltre, mi aspetto che result contenga una stringa di risposta, ma anch'essa restituisce un valore null.

Ricordare che non è possibile modificare l'applicazione client C# di terze parti. C'è qualcosa che posso fare sul lato Java?

Aggiornamento 2

Recentemente ho aggiunto una classe catena di handler che viene catturare e registrare i messaggi SOAP prime. Il messaggio inviato dal client è il seguente:

<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

Sembra probabile che il server sta ricevendo nulla perché il client è compreso il parametro nella richiesta. – DwB

+0

@DwB Non sono sicuro di cosa intendi. Potresti elaborare? –

+0

La lingua di origine ha un impatto zero sulla chiamata al servizio web. Se il servizio chiama un parametro è nullo nel server, è perché è stato inviato come nullo dal client. – DwB

risposta

5

Dopo essere stato indirizzato nella giusta direzione per @dlawrence, sono stato in grado di risolvere il mio problema. Come ho menzionato nella domanda, avevo ancora bisogno di usare un wsdl personalizzato.Ho solo dovuto apportare alcune modifiche a wsdl e al codice Java per risolvere il problema.

Ecco un diff che rappresenta le mie modifiche al 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> 

Fondamentalmente questo è stata una correzione in tre parti ...
1). Ho dovuto rimuovere l'attributo elementFormDefault="qualified" dal tag <s:schema>.
2). Quindi ho dovuto aggiungere l'attributo form="qualified" sul mio tag <s:element name="putXML" ...>.
3). Infine, dovevo assicurarmi di avere l'attributo soapAction="http://MyProject.MyPackage/putHL7Data" sul mio tag <soap:operation>.

Ecco un diff che rappresenta le mie modifiche al metodo 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 
    } 
} 

Come potete vedere, tutto quello che dovevo fare era aggiungere l'attributo targetNamespace alla mia @WebParam.

3

Hai provato a rimuovere l'attributo @WebParam? Non dovrebbe essere richiesto in quanto non vi è alcuna ambiguità con il tuo servizio web qui ed è possibile che tu abbia bisogno di impostare lo spazio dei nomi target affinché possa trovare correttamente l'attributo.

+1

Ho provato a rimuovere "@WebParam" ma non è stato rilevato alcun effetto. Dove andrebbe il "targetNamespace"? All'interno della definizione "@WebParam"? –

+0

Sì, dovrebbe essere un attributo di @WebParam. – dlawrence

+0

Grazie per il tuo suggerimento! Sono stato in grado di capire come modificare il mio wsdl personalizzato vedendo cosa aggiunge "targetNamespace" ai wsdl generati. Pubblicherò presto la mia risposta spiegando cosa ho fatto per risolvere il mio problema. –

2

ho lo stesso messaggio nella mia console glassfish. Nel mio progetto Android con la funzione ksoap ho cambiato il codice seguente:

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

.... funziona ...);

classe ho generato con http://www.wsdl2code.com