Node.js: cara menggunakan layanan web SOAP XML

99

Saya ingin tahu apa cara terbaik untuk menggunakan layanan web SOAP XML dengan node.js

Terima kasih!

WARNA PUTIH
sumber
Jika Anda menggunakan node-soap dan mengetahui cara menggunakannya, dapatkah Anda membantu saya membuat wsdl. Apakah ada generator atau tutorial yang bagus tentang cara menulis wsdl. stackoverflow.com/questions/32480481/…
Andi Giga
Jika Anda memerlukan contoh untuk panggilan layanan .NET WCF, periksa jawaban saya stackoverflow.com/a/63351804/1370029
Aliaksei Maniuk

Jawaban:

83

Anda tidak memiliki banyak pilihan.

Anda mungkin ingin menggunakan salah satu dari:

Scripter Berair
sumber
3
Terima kasih. mengalami masalah dengan pemasangan node-soap karena instalasi node-expat gagal = (
WHITECOLOR
Anda memerlukan header pengembangan ekspat untuk membuatnya
Juicy Scripter
Saya menemukan masalah yang dikatakan tentang header, tetapi saya tidak tahu di mana saya harus mendapatkannya di mana saya harus menaruhnya untuk dikompilasi, dapatkah Anda jelaskan?
WHITECOLOR
1
Mungkin Anda bisa mendapatkannya melalui alat manajemen paket untuk OS Anda. Di Ubuntu misalnyasudo apt-get install libexpat1-dev
Juicy Scripter
1
@RobertBroden, terima kasih atas pembaruannya. Lain kali, lanjutkan dan edit jawabannya (atau sarankan edit)!
Juicy Scripter
31

Saya pikir alternatifnya adalah:

Ya, ini adalah pendekatan yang agak kotor dan rendah tetapi harus bekerja tanpa masalah

tmanolatos.dll
sumber
4
Sayangnya, ini adalah metode paling andal untuk berinteraksi dengan SOAP dengan Node.js. Saya belum menemukan satu pun perpustakaan sabun yang benar-benar membuat permintaan sabun di beberapa API yang harus saya gunakan.
AlbertEngelB
1
100% kotor, tapi membawa saya ke hasil)))
markkillah
apa yang Anda maksud dengan membentuk input xml` persis?
timaschew
ya, masih bisa mengonfirmasi, non dari libs yang disebutkan di atas berfungsi sempurna.
someUser
Saya pikir "Form input xml" berarti hanya memberikan Jenis-Konten "text / xml"
SSH This
22

Jika node-soaptidak berhasil untuk Anda, cukup gunakan node requestmodul dan kemudian konversikan xml ke json jika diperlukan.

Permintaan saya tidak berfungsi node-soapdan tidak ada dukungan untuk modul itu selain dukungan berbayar, yang berada di luar sumber daya saya. Jadi saya melakukan yang berikut:

  1. mengunduh SoapUI di mesin Linux saya.
  2. menyalin WSDL xml ke file lokal
    curl http://192.168.0.28:10005/MainService/WindowsService?wsdl > wsdl_file.xml
  3. Di SoapUI saya pergi ke File > New Soap projectdan mengunggah file wsdl_file.xml.
  4. Di navigator saya memperluas salah satu layanan dan mengklik kanan permintaan dan mengklik Show Request Editor.

Dari sana saya dapat mengirim permintaan dan memastikannya berhasil dan saya juga dapat menggunakan data Rawatau HTMLuntuk membantu saya membuat permintaan eksternal.

Mentah dari SoapUI untuk permintaan saya

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

Saya menggunakan yang di atas untuk membangun yang berikut 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
sumber
terima kasih @jtlindsey. Tetapi saya mendapatkan metode 405 yang tidak diizinkan sebagai response.statusCode, response.statusMessage. Apakah Anda tahu cara memperbaikinya?
Sujoy
Ada masalah dengan URL saya. Saya menggunakan URL asli, bukan titik akhir yang dihasilkan oleh SOAPUI. Terima kasih untuk kode di atas.
Sujoy
17

Saya berhasil menggunakan soap, wsdl dan Node.js. Anda perlu menginstal sabun npm install soap

Buat server node yang disebut server.jsyang akan menentukan layanan sabun untuk dikonsumsi oleh klien jarak jauh. Layanan sabun ini menghitung Indeks Massa Tubuh berdasarkan berat (kg) dan tinggi (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);

Selanjutnya, buat client.jsfile yang akan menggunakan layanan sabun yang ditentukan oleh server.js. File ini akan memberikan argumen untuk layanan sabun dan memanggil url dengan port dan titik akhir layanan SOAP.

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

File wsdl Anda adalah protokol berbasis xml untuk pertukaran data yang menentukan cara mengakses layanan web jarak jauh. Panggil file wsdl Andabmicalculator.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>

Semoga membantu

Kim .J
sumber
1
Terima kasih banyak. Namun, saya harus menghapus "res.send (response);" dari klien dan "` "di baris terakhir file server.
Subhashi
13

Cara termudah yang saya temukan untuk hanya mengirim XML mentah ke layanan SOAP menggunakan Node.js adalah dengan menggunakan implementasi http Node.js. Ini terlihat seperti ini.

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

Anda akan mendefinisikan variabel xml sebagai xml mentah dalam bentuk string.

Tetapi jika Anda hanya ingin berinteraksi dengan layanan SOAP melalui Node.js dan melakukan panggilan SOAP biasa, bukan mengirim xml mentah, gunakan salah satu pustaka Node.js. Saya suka node-soap .

Halfstop
sumber
1
#Halfstop, dapatkah Anda memberi tahu saya cara membuat permintaan POST menggunakan node-soap?
Abhishek saini
@Abhisheksaini contoh diatas adalah sebuah postingan.
Halfstop
@Halfstop Mohon beri tahu saya cara menyertakan SOAPAtion dalam permintaan.
Sohail
12

Bergantung pada jumlah titik akhir yang Anda butuhkan, mungkin lebih mudah melakukannya secara manual.

Saya telah mencoba 10 perpustakaan "sabun nodejs" akhirnya saya melakukannya secara manual.

dam1
sumber
Saya mencoba node-soap untuk mengakses rute wsdl tetapi tidak berhasil, saya terus mendapatkan error meskipun hal yang sama bekerja di php Bisakah Anda menjawab pertanyaan saya tentang bagaimana Anda melakukannya stackoverflow.com/questions/39943122/…
Ammar Ajmal
8

Saya berhasil menggunakan paket "sabun" ( https://www.npmjs.com/package/soap ) di lebih dari 10 pelacakan WebApis (Tradetracker, Bbelboon, Affilinet, Webgains, ...).

Masalah biasanya datang dari fakta bahwa programmer tidak menyelidiki terlalu banyak tentang apa yang dibutuhkan API jarak jauh untuk menghubungkan atau mengautentikasi.

Misalnya PHP mengirim ulang cookie dari header HTTP secara otomatis, tetapi ketika menggunakan paket 'node', itu harus diatur secara eksplisit (misalnya dengan paket 'soap-cookie') ...

smentek
sumber
menggunakan sabun-cookie membantu saya melewati masalah otentikasi yang saya alami di node, terima kasih banyak!
nicolasdaudin
5

Saya menggunakan modul node net untuk membuka soket ke layanan web.

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

Kirim permintaan sabun

/* 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 soap response, saya menggunakan 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();
        }
    }
});

Semoga bisa membantu seseorang

Vince Lowe
sumber
1
mengapa Anda melakukan ini daripada menggunakan modul http?
Will Munn
0

Menambah solusi Kim .J : Anda dapat menambahkan preserveWhitespace=trueuntuk menghindari kesalahan Whitespace. Seperti ini:

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

Anda juga dapat menggunakan wsdlrdr. EasySoap pada dasarnya adalah penulisan ulang wsdlrdr dengan beberapa metode tambahan. Berhati-hatilah karena easysoap tidak memiliki metode getNamespace yang tersedia di wsdlrdr.

allen_mxk686
sumber
0

Bagi mereka yang baru mengenal SOAPdan menginginkan penjelasan dan panduan singkat, saya sangat merekomendasikan artikel media yang luar biasa ini .

Anda juga dapat menggunakan node-soap paket , dengan tutorial sederhana ini .

MajidJafari
sumber
0

Jika Anda hanya memerlukan konversi satu kali, https://www.apimatic.io/dashboard?modal=transform memungkinkan Anda melakukan ini dengan membuat akun gratis (tanpa afiliasi, ini hanya berfungsi untuk saya).

Jika Anda bertransformasi menjadi Swagger 2.0, Anda dapat membuat js lib dengan

$ 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
palu
sumber