Node.js: Verwendung des SOAP XML-Webdienstes

99

Ich frage mich, wie SOAP XML-Webdienst mit node.js am besten genutzt werden kann

Vielen Dank!

WEISSE FARBE
quelle
Wenn Sie Node-Soap verwenden und herausfinden, wie es verwendet wird, können Sie mir beim Erstellen einer WSDL helfen. Gibt es einen Generator oder ein gutes Tutorial, wie man die WSDL schreibt? stackoverflow.com/questions/32480481/…
Andi Giga
Wenn
Aliaksei Maniuk

Antworten:

83

Sie haben nicht so viele Möglichkeiten.

Sie möchten wahrscheinlich eines der folgenden Elemente verwenden:

Juicy Scripter
quelle
3
Vielen Dank. Probleme mit der Node-Soap-Installation, da Node-Expat-Installationsfehler = (
WHITECOLOR
Sie benötigen Expat-Entwicklungsheader, um es zu erstellen
Juicy Scripter
Ich fand das Problem, das über Header gesagt wurde, aber ich weiß nicht, wo ich es bekommen soll, wo ich es zum Kompilieren ablegen soll. Könnten Sie das bitte erklären?
WHITECOLOR
1
Wahrscheinlich können Sie sie über Paketverwaltungstools für Ihr Betriebssystem erhalten. Auf Ubuntu zum Beispielsudo apt-get install libexpat1-dev
Juicy Scripter
1
@ RobertBroden, danke für das Update. Bitte bearbeiten Sie das nächste Mal die Antwort (oder schlagen Sie eine Bearbeitung vor)!
Juicy Scripter
31

Ich denke, dass eine Alternative wäre:

Ja, dies ist ein ziemlich schmutziger und niedriger Ansatz, aber er sollte ohne Probleme funktionieren

tmanolatos
quelle
4
Leider ist dies die zuverlässigste Methode für die Interaktion mit SOAP mit Node.js. Ich habe noch keine einzige Seifenbibliothek gefunden, die Seifenanfragen für die wenigen APIs, die ich verwenden muss, ordnungsgemäß stellt.
AlbertEngelB
1
100% dreckig, brachte mich aber zu Ergebnissen)))
Markkillah
Was meint ihr alle damit, Input xml` genau zu bilden?
Timaschew
Ja, kann immer noch bestätigen, dass keine der oben genannten Bibliotheken perfekt funktioniert.
someUser
Ich denke, "Formulareingabe xml" bedeutet nur, einen Inhaltstyp von "text / xml" anzugeben
SSH Diesen
22

Wenn node-soapdies bei Ihnen nicht funktioniert, verwenden Sie einfach das node requestModul und konvertieren Sie die XML-Datei bei Bedarf in JSON.

Meine Anfrage funktionierte nicht node-soapund es gibt keinen Support für dieses Modul, außer dem bezahlten Support, der über meine Ressourcen hinausging. Also habe ich folgendes gemacht:

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

Von dort aus konnte ich eine Anfrage senden und sicherstellen, dass sie funktionierte, und ich konnte auch die Daten Rawoder HTMLverwenden, um eine externe Anfrage zu erstellen.

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 Obige verwendet, um Folgendes zu erstellen 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);
jtlindsey
quelle
danke @jtlindsey. Aber ich bekomme 405 Methode nicht als response.statusCode, response.statusMessage erlaubt. Wissen Sie vielleicht, wie Sie das beheben können?
Sujoy
Es gab ein Problem mit meiner URL. Ich habe die ursprüngliche URL anstelle des von SOAPUI generierten Endpunkts verwendet. Danke für den obigen Code.
Sujoy
17

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

Erstellen Sie einen Knotenserver mit dem Namen server.js, der den Seifendienst definiert, der von einem Remoteclient verwendet werden soll. Dieser Seifenservice berechnet den Body Mass Index basierend auf Gewicht (kg) und Größe (m).

const soap = require('soap');
const express = require('express');
const 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
 */
const service = {
  BMI_Service: {
    BMI_Port: {
      calculateBMI(args) {
        //console.log(Date().getFullYear())
        const year = new Date().getFullYear();
        const n = args.weight / (args.height * args.height);
        console.log(n);
        return { bmi: n };
      }
    }
  }
};
// xml data is extracted from wsdl file created
const xml = require('fs').readFileSync('./bmicalculator.wsdl', 'utf8');
//create an express server and pass it to a soap server
const server = app.listen(3030, function() {
  const host = '127.0.0.1';
  const port = server.address().port;
});
soap.listen(server, '/bmicalculator', service, xml);

Erstellen Sie als Nächstes eine client.jsDatei, die den durch definierten Seifendienst verwendet server.js. Diese Datei enthält Argumente für den Seifendienst und ruft die URL mit den SOAP-Dienstports und -Endpunkten auf.

const express = require('express');
const soap = require('soap');
const url = 'http://localhost:3030/bmicalculator?wsdl';
const 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 definiert, wie auf einen Remote-Webdienst zugegriffen wird. Rufen Sie Ihre wsdl-Datei aufbmicalculator.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>

Ich hoffe es hilft

Kim .J
quelle
1
Ich danke dir sehr. Ich musste jedoch "res.send (response)" entfernen. vom Client und "` "in der letzten Zeile der Serverdatei.
Subhashi
13

Der einfachste Weg, Roh-XML mit Node.js an einen SOAP-Dienst zu senden, ist die Verwendung der http-Implementierung von Node.js. 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 rohe XML in Form einer Zeichenfolge definiert.

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

Halfstop
quelle
1
#Halfstop, können Sie mir bitte sagen, wie ich eine POST-Anfrage mit Node-Soap stellen soll?
Abhishek Saini
@Abhisheksaini das obige Beispiel ist ein Beitrag.
Halfstop
@Halfstop Bitte sagen Sie mir, wie ich SOAPAction in die Anfrage aufnehmen soll.
Sohail
12

Abhängig von der Anzahl der benötigten Endpunkte ist es möglicherweise einfacher, dies manuell zu tun.

Ich habe 10 Bibliotheken "soap nodejs" ausprobiert. Ich mache es endlich manuell.

dam1
quelle
Ich habe Node-Soap für den Zugriff auf die WSDL-Route ausprobiert, aber es funktioniert nicht. Ich erhalte immer wieder Fehler, obwohl das Gleiche in PHP funktioniert. Können Sie meine Frage beantworten, wie Sie es gemacht haben ? Stackoverflow.com/questions/39943122/…
Ammar Ajmal
8

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

Probleme ergeben sich normalerweise aus der Tatsache, dass Programmierer nicht zu viel darüber untersuchen, was die Remote-API benötigt, um eine Verbindung herzustellen oder sich zu authentifizieren.

Zum Beispiel sendet PHP Cookies von HTTP-Headern automatisch erneut, aber wenn Sie das 'Node'-Paket verwenden, müssen Sie dies explizit festlegen (zum Beispiel durch das' Soap-Cookie'-Paket) ...

Smentek
quelle
Die Verwendung von Seifen-Cookies hat mir geholfen, ein Authentifizierungsproblem zu umgehen, das ich im Knoten hatte. Vielen Dank!
Nicolasdaudin
5

Ich habe das Node-Net-Modul 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);          
    }
});

Seifenanfragen senden

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

Seifenantwort analysieren, ich habe Modul - xml2js verwendet

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

Vince Lowe
quelle
1
Warum sollten Sie dies tun, anstatt das http-Modul zu verwenden?
Will Munn
0

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

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

Sie können auch wsdlrdr verwenden. EasySoap ist im Grunde ein Umschreiben von wsdlrdr mit einigen zusätzlichen Methoden. Achten Sie darauf, dass easysoap nicht über die getNamespace-Methode verfügt, die unter wsdlrdr verfügbar ist.

allen_mxk686
quelle
0

Für diejenigen, die neu in diesem Bereich sind SOAPund eine kurze Erklärung und Anleitung wünschen, empfehle ich diesen großartigen Artikel .

Mit diesem einfachen Tutorial können Sie auch das node-soap Paket verwenden .

MajidJafari
quelle
0

Wenn Sie nur eine einmalige Konvertierung benötigen, können Sie dies unter https://www.apimatic.io/dashboard?modal=transform tun, indem Sie ein kostenloses Konto erstellen (keine Zugehörigkeit, es hat nur bei mir funktioniert).

Wenn Sie sich in Swagger 2.0 verwandeln, können Sie eine js lib mit erstellen

$ wget https://repo1.maven.org/maven2/io/swagger/codegen/v3/swagger-codegen-cli/3.0.20/swagger-codegen-cli-3.0.20.jar \
  -O swagger-codegen-cli.jar
$ java -jar swagger-codegen-cli.jar generate \
  -l javascript -i orig.wsdl-Swagger20.json -o ./fromswagger
Unhammer
quelle