2011-12-28 23 views
71

mi chiedo qual è il modo migliore per consumare SOAP servizio Web XML con node.jsNode.js: come consumare SOAP servizio Web XML

Grazie!

+0

Nel caso in cui si utilizzi node-soap e si è capito come utilizzarlo, potresti aiutarmi con la creazione di un wsdl. C'è un generatore o un buon tutorial su come scrivere il wsdl. http://stackoverflow.com/questions/32480481/creating-a-soap-webservice-with-node-soap –

risposta

61

Non hai molte opzioni.

Probabilmente desidera utilizzare uno di:

+2

Grazie. avendo problemi con l'installazione di node-soap perché l'installazione di node-expat fallisce = ( – WHITECOLOR

+0

Avrete bisogno di intestazioni di sviluppo expat per costruirlo –

+0

Ho trovato che il problema è stato detto sulle intestazioni, ma non so dove dovrei trovarlo dove dovrebbe Lo metto a compilare, potresti spiegare, per favore? – WHITECOLOR

24

Penso che un alternativa sarebbe quella di:

Sì, questo è un approccio piuttosto sporca e di basso livello, ma dovrebbe funzionare senza problemi

+2

Purtroppo, questo è il metodo più affidabile per interagire con SOAP con Node.js. Devo ancora trovare una singola libreria di sapone che faccia correttamente le richieste di sapone sulla manciata di API che devo usare. –

+0

100% sporco, ma mi ha portato ai risultati))) – markkillah

+0

cosa intendi con per formare input xml' esattamente? – timaschew

9

A seconda del numero di endpoint è necessario, può essere più facile farlo manualmente.

Ho provato 10 librerie "soap nodejs". Finalmente lo faccio manualmente.

+0

Ho provato il nodo-sapone per accedere alla rotta wsdl ma non funziona, continuo a ricevere errori anche se la stessa cosa funziona in php Puoi rispondere alla mia domanda su come lo hai fatto http://stackoverflow.com/questions/39943122/php-soap-client-equivalent-in-nodejs –

7

ho usato con successo " soap "(https://www.npmjs.com/package/soap) su più di 10 tracking WebApis (Tradetracker, Bbelboon, Affilinet, Webgains, ...).

I problemi di solito derivano dal fatto che i programmatori non indagano molto su quali siano le API remote necessarie per connettersi o autenticarsi.

Per esempio PHP invia nuovamente i cookie da intestazioni HTTP automaticamente, ma quando si utilizza il pacchetto 'nodo', si deve essere in modo esplicito impostare (ad esempio 'soap-cookie' pacchetto) ...

+0

utilizzando soap-cookie mi ha aiutato a superare un problema di autenticazione che stavo avendo nel nodo, grazie mille! – nicolasdaudin

5

Ho usato il nodo modulo net per aprire un socket sul webservice.

/* on Login request */ 
socket.on('login', function(credentials /* {username} {password} */){ 
    if(!_this.netConnected){ 
     _this.net.connect(8081, '127.0.0.1', function() { 
      logger.gps('('+socket.id + ') '+credentials.username+' connected to: 127.0.0.1:8081'); 
      _this.netConnected = true; 
      _this.username = credentials.username; 
      _this.password = credentials.password; 
      _this.m_RequestId = 1; 
      /* make SOAP Login request */ 
      soapGps('', _this, 'login', credentials.username);    
     });   
    } else { 
     /* make SOAP Login request */ 
     _this.m_RequestId = _this.m_RequestId +1; 
     soapGps('', _this, 'login', credentials.username);   
    } 
}); 

Invia sapone chiede risposta SOAP

/* SOAP request func */ 
module.exports = function soapGps(xmlResponse, client, header, data) { 
    /* send Login request */ 
    if(header == 'login'){ 
     var SOAP_Headers = "POST /soap/gps/login HTTP/1.1\r\nHost: soap.example.com\r\nUser-Agent: SOAP-client/SecurityCenter3.0\r\n" + 
          "Content-Type: application/soap+xml; charset=\"utf-8\"";   
     var SOAP_Envelope= "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + 
          "<env:Envelope xmlns:env=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:SOAP-ENC=\"http://www.w3.org/2003/05/soap-encoding\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:n=\"http://www.example.com\"><env:Header><n:Request>" + 
          "Login" + 
          "</n:Request></env:Header><env:Body>" + 
          "<n:RequestLogin xmlns:n=\"http://www.example.com.com/gps/soap\">" + 
          "<n:Name>"+data+"</n:Name>" + 
          "<n:OrgID>0</n:OrgID>" +           
          "<n:LoginEntityType>admin</n:LoginEntityType>" + 
          "<n:AuthType>simple</n:AuthType>" + 
          "</n:RequestLogin></env:Body></env:Envelope>"; 

     client.net.write(SOAP_Headers + "\r\nContent-Length:" + SOAP_Envelope.length.toString() + "\r\n\r\n"); 
     client.net.write(SOAP_Envelope); 
     return; 
    } 

Parse, ho usato il modulo - xml2js

var parser = new xml2js.Parser({ 
    normalize: true, 
    trim: true, 
    explicitArray: false 
}); 
//client.net.setEncoding('utf8'); 

client.net.on('data', function(response) { 
    parser.parseString(response); 
}); 

parser.addListener('end', function(xmlResponse) { 
    var response = xmlResponse['env:Envelope']['env:Header']['n:Response']._; 
    /* handle Login response */ 
    if (response == 'Login'){ 
     /* make SOAP LoginContinue request */ 
     soapGps(xmlResponse, client, ''); 
    } 
    /* handle LoginContinue response */ 
    if (response == 'LoginContinue') { 
     if(xmlResponse['env:Envelope']['env:Body']['n:ResponseLoginContinue']['n:ErrCode'] == "ok") {   
      var nTimeMsecServer = xmlResponse['env:Envelope']['env:Body']['n:ResponseLoginContinue']['n:CurrentTime']; 
      var nTimeMsecOur = new Date().getTime(); 
     } else { 
      /* Unsuccessful login */ 
      io.to(client.id).emit('Error', "invalid login"); 
      client.net.destroy(); 
     } 
    } 
}); 

Speranza che aiuta qualcuno

+0

perché dovresti farlo invece di usare il modulo http? –

11

Il modo più semplice che ho trovato per inviare solo grezzo XML per un servizio SOAP che utilizza Node.js consiste nell'utilizzare l'implementazione http di Node.js. Sembra così

var http = require('http'); 
var http_options = { 
    hostname: 'localhost', 
    port: 80, 
    path: '/LocationOfSOAPServer/', 
    method: 'POST', 
    headers: { 
    'Content-Type': 'application/x-www-form-urlencoded', 
    'Content-Length': xml.length 
    } 
} 

var req = http.request(http_options, (res) => { 
    console.log(`STATUS: ${res.statusCode}`); 
    console.log(`HEADERS: ${JSON.stringify(res.headers)}`); 
    res.setEncoding('utf8'); 
    res.on('data', (chunk) => { 
    console.log(`BODY: ${chunk}`); 
    }); 

    res.on('end',() => { 
    console.log('No more data in response.') 
    }) 
}); 

req.on('error', (e) => { 
    console.log(`problem with request: ${e.message}`); 
}); 

// write data to request body 
req.write(xml); // xml would have been set somewhere to a complete xml document in the form of a string 
req.end(); 

Si sarebbe definita la variabile xml come xml grezzo sotto forma di stringa.

Ma se si desidera solo interagire con un servizio SOAP tramite Node.js e effettuare chiamate SOAP regolari, al contrario dell'invio di xml non elaborati, utilizzare una delle librerie Node.js. Mi piace node-soap.

+1

#Halfstop, potresti dirmi come fare la richiesta POST usando node-soap? –

+0

@Abhisheksaini l'esempio sopra è un post. – Halfstop

8

sono riuscito a usare SOAP, WSDL e Node.js È necessario installare il sapone con npm install soap

Creare un server nodo denominato server.js che definirà il servizio sapone per essere consumato da un client remoto. Questo servizio di sapone calcola l'indice di massa corporea in base al peso (kg) e all'altezza (m).

var soap = require('soap'); 
var express = require('express'); 
var app = express(); 
/** 
-this is remote service defined in this file, that can be accessed by clients, who will supply args 
-response is returned to the calling client 
-our service calculates bmi by dividing weight in kilograms by square of height in metres 
**/ 
var service = { 
    BMI_Service : { 
     BMI_Port :{ 
      calculateBMI:function(args){ 
       //console.log(Date().getFullYear()) 
       var year = new Date().getFullYear(); 
       var n = (args.weight)/(args.height*args.height); 
       console.log(n); 
       return {bmi: n}; 
      } 
     } 
    } 
} 
// xml data is extracted from wsdl file created 
var xml = require('fs').readFileSync('./bmicalculator.wsdl','utf8'); 
//create an express server and pass it to a soap server 
var server = app.listen(3030,function(){ 
var host = "127.0.0.1"; 
var port = server.address().port; 
}); 
`soap.listen(server,'/bmicalculator',service,xml); 

Successivamente, creare un file client.js che consumerà servizio sapone definito da server.js. Questo file fornirà argomenti per il servizio soap e chiamerà l'url con le porte di servizio e gli endpoint di SOAP.

var express = require('express'); 
var soap = require('soap'); 
var url = "http://localhost:3030/bmicalculator?wsdl"; 
var args = {weight:65.7,height:1.63}; 
soap.createClient(url,function(err,client){ 
if(err) 
console.error(err); 
else { 
client.calculateBMI(args,function(err,response){ 
if(err) 
console.error(err); 
else { 
console.log(response); 
res.send(response); 
} 
}) 
} 
}); 

il file WSDL è un protocollo basato su XML per lo scambio dati che definisce come per accedere a un servizio Web remoto. Chiamate il file WSDL bmicalculator.wsdl

<definitions name="HelloService" 
targetNamespace="http://www.examples.com/wsdl/HelloService.wsdl" 
xmlns="http://schemas.xmlsoap.org/wsdl/" 
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" 
xmlns:tns="http://www.examples.com/wsdl/HelloService.wsdl" 
xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 

<message name="getBMIRequest"> 
<part name="weight" type="xsd:float"/> 
<part name="height" type="xsd:float"/> 
</message> 

<message name="getBMIResponse"> 
<part name="bmi" type="xsd:float"/> 
</message> 

<portType name="Hello_PortType"> 
<operation name="calculateBMI"> 
<input message="tns:getBMIRequest"/> 
<output message="tns:getBMIResponse"/> 
</operation> 
</portType> 

<binding name="Hello_Binding" type="tns:Hello_PortType"> 
<soap:binding style="rpc" 
transport="http://schemas.xmlsoap.org/soap/http"/> 
<operation name="calculateBMI"> 
<soap:operation soapAction="calculateBMI"/> 
<input> 
<soap:body 
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" 
namespace="urn:examples:helloservice" 
use="encoded"/> 
</input> 
<output> 
<soap:body 
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" 
namespace="urn:examples:helloservice" 
use="encoded"/> 
</output> 
</operation> 
</binding> 

<service name="BMI_Service"> 
<documentation>WSDL File for HelloService</documentation> 
<port binding="tns:Hello_Binding" name="BMI_Port"> 
<soap:address 
location="http://localhost:3030/bmicalculator/" /> 
</port> 
</service> 
</definitions> 

Speranza che aiuta

5

Se node-soap non funziona per voi, basta usare noderequest modulo e poi convertire il codice XML a JSON, se necessario.

La mia richiesta non funzionava con node-soap e non c'è supporto per quel modulo oltre al supporto a pagamento, che era oltre le mie risorse. Così ho fatto quanto segue:

  1. scaricato SoapUI sulla mia macchina Linux.
  2. copiato il codice XML WSDL in un file locale
    curl http://192.168.0.28:10005/MainService/WindowsService?wsdl > wsdl_file.xml
  3. In SoapUI sono andato a File > New Soap project e caricato il mio wsdl_file.xml.
  4. Nel navigatore ho espanso uno dei servizi e fatto clic con il tasto destro su la richiesta e cliccato su Show Request Editor.

Da lì ho potuto inviare una richiesta e assicurarsi che ha funzionato e ho potuto anche usare i Raw o HTML dati per aiutare a costruire una richiesta esterna.

crudo di SoapUI per la mia richiesta

POST http://192.168.0.28:10005/MainService/WindowsService HTTP/1.1 
Accept-Encoding: gzip,deflate 
Content-Type: text/xml;charset=UTF-8 
SOAPAction: "http://Main.Service/AUserService/GetUsers" 
Content-Length: 303 
Host: 192.168.0.28:10005 
Connection: Keep-Alive 
User-Agent: Apache-HttpClient/4.1.1 (java 1.5) 

XML da SoapUI

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:qtre="http://Main.Service"> 
    <soapenv:Header/> 
    <soapenv:Body> 
     <qtre:GetUsers> 
     <qtre:sSearchText></qtre:sSearchText> 
     </qtre:GetUsers> 
    </soapenv:Body> 
</soapenv:Envelope> 

ho usato il sopra per costruire il seguente noderequest:

var request = require('request'); 
let xml = 
`<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:qtre="http://Main.Service"> 
    <soapenv:Header/> 
    <soapenv:Body> 
     <qtre:GetUsers> 
     <qtre:sSearchText></qtre:sSearchText> 
     </qtre:GetUsers> 
    </soapenv:Body> 
</soapenv:Envelope>` 

var options = { 
    url: 'http://192.168.0.28:10005/MainService/WindowsService?wsdl', 
    method: 'POST', 
    body: xml, 
    headers: { 
    'Content-Type':'text/xml;charset=utf-8', 
    'Accept-Encoding': 'gzip,deflate', 
    'Content-Length':xml.length, 
    'SOAPAction':"http://Main.Service/AUserService/GetUsers" 
    } 
}; 

let callback = (error, response, body) => { 
    if (!error && response.statusCode == 200) { 
    console.log('Raw result', body); 
    var xml2js = require('xml2js'); 
    var parser = new xml2js.Parser({explicitArray: false, trim: true}); 
    parser.parseString(body, (err, result) => { 
     console.log('JSON result', result); 
    }); 
    }; 
    console.log('E', response.statusCode, response.statusMessage); 
}; 
request(options, callback); 
0

Aggiungendo a Kim .J's solution: voi possibile aggiungere preserveWhitespace=true in o rder per evitare un errore di spazio bianco. In questo modo:

soap.CreateClient(url,preserveWhitespace=true,function(...){ 
Problemi correlati