Nœud.js: comment consommer le service Web XML SOAP

Je me demande Quelle est la meilleure façon de consommer le service Web XML SOAP avec node.js

Merci!

78
demandé sur WHITECOLOR 2011-12-28 15:22:15

11 réponses

Vous n'avez pas beaucoup d'options.

Vous voudrez probablement utiliser l'un des éléments suivants:

68
répondu Juicy Scripter 2016-11-02 13:03:07

Je pense qu'une solution serait de:

Oui, c'est une approche plutôt sale et de bas niveau mais cela devrait fonctionner sans problèmes

28
répondu tmanolatos 2014-04-06 17:31:11

La façon la plus simple que j'ai trouvée d'envoyer simplement du XML brut à un service SOAP en utilisant Node.js est d'utiliser le nœud.implémentation http js. Il ressemble à ceci.

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

Vous auriez défini la variable xml comme xml brut sous la forme d'une chaîne.

Mais si vous voulez juste interagir avec un service SOAP via Node.js et effectuer des appels SOAP réguliers, par opposition à l'envoi de xml brut, utilisez l'un des nœuds.les librairies js. J'aime nœud de savon.

13
répondu Halfstop 2016-05-20 18:57:25

J'ai réussi à utiliser soap, WSDL et Node.js Vous devez installer soap avec npm install soap

Créez un serveur de nœuds appelé server.js qui définira le service soap à utiliser par un client distant. Ce service de savon calcule L'indice de masse corporelle basé sur le poids (kg) et la taille (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);

Ensuite, créez un fichier client.js qui consommera le service soap défini par server.js. Ce fichier fournira des arguments pour le service soap et appellera l'url avec les ports et les points de terminaison du service 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);
}
})
}
});

Votre le fichier wsdl est un protocole basé sur xml pour l'échange de données qui définit comment accéder à un service web distant. Appelez votre fichier 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>

J'espère que ça aide

11
répondu Kim .J 2017-01-24 20:02:47

Selon le nombre de points de terminaison dont vous avez besoin, il peut être plus facile de le faire manuellement.

J'ai essayé 10 bibliothèques "soap nodejs" je le fais finalement manuellement.

9
répondu dam1 2018-02-19 08:52:08

Si node-soap ne fonctionne pas pour vous, utilisez simplementnode request module, puis convertir le xml en json si nécessaire.

Ma demande ne fonctionnait pas avec node-soap et il n'y a pas de support pour ce module au-delà du support payé, qui était au-delà de mes ressources. J'ai donc fait ce qui suit:

  1. téléchargé SoapUI sur ma machine Linux.
  2. copié le fichier xml WSDL dans un fichier local
    curl http://192.168.0.28:10005/MainService/WindowsService?wsdl > wsdl_file.xml
  3. Dans SoapUI je suis allé à File > New Soap project et téléchargé mon wsdl_file.xml.
  4. dans le navigateur j'ai élargi l'un des services et fait un clic droit la requête et cliqué sur Show Request Editor.

À partir de là, je pourrais envoyer une requête et m'assurer que cela fonctionnait et je pourrais également utiliser les données Raw ou HTML pour m'aider à construire une requête externe.

Raw de SoapUI pour ma demande

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 à partir de 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> 

J'ai utilisé ce qui précède pour construire ce qui suit node request:

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);
8
répondu jtlindsey 2017-08-29 02:26:44

J'ai utilisé avec succès le paquet "soap" (https://www.npmjs.com/package/soap ) sur plus de 10 webapis de suivi (Tradetracker, Bbelboon, Affilinet, Webgains,...).

Les problèmes viennent généralement du fait que les programmeurs n'enquêtent pas beaucoup sur les besoins de L'API distante pour se connecter ou s'authentifier.

Par exemple, PHP renvoie automatiquement les cookies des en-têtes HTTP, mais lors de l'utilisation du paquet 'node', il doit être explicitement défini (par exemple par "savon-cookie" paquet)...

7
répondu smentek 2015-04-17 16:21:04
5
répondu euroblaze 2014-06-28 19:55:09

J'ai utilisé le module node net pour ouvrir un socket au 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);          
    }
});

Envoyer des requêtes 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;
    }

Analyser la réponse soap, j'ai utilisé le 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();
        }
    }
});

J'espère que ça aide quelqu'un

5
répondu Vince Lowe 2015-11-14 10:46:19

Ajouter à Kim .Solution de J : Vous pouvez ajouter preserveWhitespace=true afin d'éviter une erreur D'Espace. Comme ceci:

soap.CreateClient(url,preserveWhitespace=true,function(...){
0
répondu J.Aliaga 2018-01-12 11:16:38

Vous pouvez également utiliser wsdlrdr. EasySoap est essentiellement la réécriture de wsdlrdr avec quelques méthodes supplémentaires. Veillez à ce qu'easysoap n'ait pas la méthode getNamespace disponible sur wsdlrdr.

0
répondu user10152282 2018-08-23 09:54:54