webentwicklung-frage-antwort-db.com.de

Node.js: Wie verbrauchen? SOAP XML-Webdienst

Ich frage mich, was der beste Weg ist, SOAP XML-Webdienst mit node.js zu verwenden

Vielen Dank!

83
WHITECOLOR

Du hast nicht so viele Möglichkeiten.

Sie möchten wahrscheinlich eines der folgenden verwenden:

72
Juicy Scripter

Ich denke, eine Alternative wäre:

  • verwenden Sie ein Tool wie SoapUI ( http://www.soapui.org ), um Eingabe- und Ausgabe-XML-Nachrichten aufzuzeichnen
  • verwenden Sie die Knotenanforderung ( https://github.com/mikeal/request ), um eine Eingabe-XML-Nachricht zum Senden (POST) der Anforderung an den Web-Service zu bilden (beachten Sie, dass standardmäßige JavaScript-Vorlagenmechanismen wie EJS ( http : //embeddedjs.com/ ) oder Schnurrbart ( https://github.com/janl/mustache.js ) könnte Ihnen hier helfen) und schließlich
  • verwenden Sie einen XML-Parser, um Antwortdaten für JavaScript-Objekte zu deserialisieren

Ja, dies ist ein ziemlich schmutziger Ansatz auf niedriger Ebene, sollte jedoch problemlos funktionieren

30
tmanolatos

Am einfachsten habe ich festgestellt, dass ich mit Node.js einfach unformatiertes XML an einen SOAP - Dienst senden soll, indem Sie die http-Implementierung Node.js verwenden. Es sieht aus wie das.

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

Sie hätten die XML-Variable als Roh-XML in Form einer Zeichenfolge definiert.

Wenn Sie jedoch lediglich mit einem SOAP - Dienst über Node.js interagieren und regelmäßig SOAP - Aufrufe durchführen möchten, anstatt rohe XML-Dateien zu senden, verwenden Sie eine der Node.js-Bibliotheken. Ich mag node-soap .

14
Halfstop

Wenn node-soap für Sie nicht funktioniert, verwenden Sie einfach das Modul noderequest und konvertieren Sie die xml-Datei in json, falls erforderlich. 

Meine Anfrage funktionierte nicht mit node-soap und es gibt keine Unterstützung für dieses Modul über den bezahlten Support hinaus, was über meine Ressourcen hinausging. Also habe ich folgendes gemacht: 

  1. SoapUI auf meinem Linux-Rechner heruntergeladen.
  2. die WSDL-XML-Datei wurde in eine lokale Datei kopiert
    curl http://192.168.0.28:10005/MainService/WindowsService?wsdl > wsdl_file.xml
  3. In SoapUI ging ich zu File > New Soap project und lud meinen wsdl_file.xml hoch.
  4. Im Navigator habe ich einen der Dienste erweitert und mit der rechten Maustaste auf die Anfrage geklickt und auf Show Request Editor geklickt.

Von dort aus konnte ich eine Anfrage senden und sicherstellen, dass sie funktionierte. Außerdem konnte ich die Raw- oder HTML-Daten verwenden, um mir beim Erstellen einer externen Anfrage zu helfen.

Raw von SoapUI für meine Anfrage

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

Ich habe das oben genannte benutzt, um die folgende noderequest zu erstellen:

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);
13
jtlindsey

Ich habe es geschafft, Seife, Wsdl und Node.js.__ zu verwenden. Sie müssen Seife mit npm install soap installieren.

Erstellen Sie einen Knotenserver namens server.js, der den von einem Remote-Client zu verwendenden Soap-Service definiert. Dieser Seifenservice berechnet den Body-Mass-Index basierend auf Gewicht (kg) und Höhe (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);

Als Nächstes erstellen Sie eine client.js-Datei, die den durch server.js definierten Seifendienst beansprucht. Diese Datei enthält Argumente für den Soap-Service und ruft die URL mit den SOAP-Service-Ports und -Endpunkten auf.

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

Ihre wsdl-Datei ist ein XML-basiertes Protokoll für den Datenaustausch, das den Zugriff auf einen Remote-Webdienst definiert. Rufen Sie Ihre WSDL-Datei bmicalculator.wsdl auf.

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

Ich hoffe es hilft

12
Kim .J

Abhängig von der Anzahl der benötigten Endpunkte ist es möglicherweise einfacher, sie manuell auszuführen.

Ich habe 10 Bibliotheken "soap nodejs" ausprobiert und mache es schließlich manuell. 

9
dam1

Ich habe das "soap" -Paket ( https://www.npmjs.com/package/soap ) erfolgreich für mehr als 10 Tracking-WebApis (Tradetracker, Bbelboon, Affilinet, Webgains, ...) verwendet. 

Probleme ergeben sich in der Regel aus der Tatsache, dass Programmierer nicht zu viel darüber nachdenken, welche Remote-API für die Verbindung oder Authentifizierung erforderlich ist. 

Zum Beispiel sendet PHP Cookies automatisch aus HTTP-Headern erneut. Wenn Sie jedoch das 'node'-Paket verwenden, müssen Sie dies explizit festlegen (z. B. durch das' soap-cookie'-Paket) ... 

8
smentek

Ich habe das Knotennetzmodul verwendet, um einen Socket für den Webservice zu öffnen.

/* 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);          
    }
});

Senden Sie Seifenanfragen

/* 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 Seife Antwort, ich verwendete Modul - 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();
        }
    }
});

Hoffe es hilft jemandem

5
Vince Lowe
5
euroblaze

Hinzufügen von Kim .Js Lösung : Sie können preserveWhitespace=true hinzufügen, um einen Whitespace-Fehler zu vermeiden. So was:

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

Sie können auch wsdlrdr verwenden. EasySoap schreibt wsdlrdr grundsätzlich mit einigen zusätzlichen Methoden um. Seien Sie vorsichtig, dass easysoap nicht über die getNamespace-Methode verfügt, die unter wsdlrdr verfügbar ist.

0
user10152282

Für diejenigen, die neu in SOAP sind und eine schnelle Erklärung und Anleitung wünschen, empfehle ich dieses großartige Medium Artikel .

Sie können auch node-soappackage verwenden, mit diesem einfachen Tutorial .

0
MajidJafari