Node.js: come utilizzare il servizio Web XML SOAP

Mi chiedo quale sia il modo migliore per utilizzare il servizio Web XML SOAP con node.js

Grazie!

Non hai molte opzioni.

Probabilmente vorrai usare uno di:

  • node-soap
  • soap forte (riscrittura di node-soap )
  • easysoap

Penso che un’alternativa sarebbe:

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

Il modo più semplice in cui ho trovato di inviare semplicemente XML non elaborato a un servizio SOAP utilizzando 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(); 

Avresti definito la variabile xml come xml grezzo sotto forma di stringa.

Ma se vuoi semplicemente interagire con un servizio SOAP tramite Node.js e fare regolari chiamate SOAP, invece di inviare xml raw, usa una delle librerie Node.js. Mi piace il soap del nodo .

Sono riuscito a usare soap, wsdl e Node.js È necessario installare soap con npm install soap

Creare un server nodo chiamato server.js che definirà il servizio soap da consumare da un client remoto. Questo servizio di soap 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, crea un file client.js che utilizzerà il servizio soap 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 di dati che definisce come accedere a un servizio Web remoto. Chiama il tuo file wsdl bmicalculator.wsdl

                            WSDL File for HelloService      

Spero che sia d’aiuto

Se node-soap non funziona per te, basta usare il modulo di request node e quindi convertire il xml in json se necessario.

La mia richiesta non funzionava con node-soap e non c’è supporto per quel modulo oltre al supporto pagato, che era al di fuori delle mie risorse. Quindi ho fatto quanto segue:

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

Da lì ho potuto inviare una richiesta e assicurarmi che funzionasse e potrei anche utilizzare i dati Raw o HTML per aiutarmi a creare una richiesta esterna.

Raw da 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

         

Ho usato quanto sopra per build la seguente request node :

 var request = require('request'); let xml = `       ` 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); 

A seconda del numero di endpoint necessari, potrebbe essere più semplice eseguirlo manualmente.

Ho provato 10 librerie “soap nodejs”, finalmente lo faccio manualmente.

Ho usato con successo il pacchetto “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.

Ad esempio, PHP rinvia automaticamente i cookie dalle intestazioni HTTP, ma quando si utilizza il pacchetto ‘nodo’, deve essere impostato in modo esplicito (ad esempio dal pacchetto ‘soap-cookie’) …

Ho usato il modulo net node 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 richieste di 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= "" + "" + "Login" + "" + "" + ""+data+"" + "0" + "admin" + "simple" + ""; client.net.write(SOAP_Headers + "\r\nContent-Length:" + SOAP_Envelope.length.toString() + "\r\n\r\n"); client.net.write(SOAP_Envelope); return; } 

Parse soap response, ho usato module – 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(); } } }); 

Spero che aiuti qualcuno

Aggiungendo alla soluzione di Kim .J : puoi aggiungere preserveWhitespace=true per evitare un errore di spazio bianco. Come questo:

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

Puoi anche usare wsdlrdr. EasySoap è fondamentalmente una riscrittura di wsdlrdr con alcuni metodi aggiuntivi. Fai attenzione che easysoap non ha il metodo getNamespace che è disponibile su wsdlrdr.