Node.js: как использовать веб-сервис SOAP XML - PullRequest
86 голосов
/ 28 декабря 2011

Интересно, как лучше всего использовать веб-сервис SOAP XML с node.js

Спасибо!

Ответы [ 12 ]

75 голосов
/ 28 декабря 2011

У вас не так много вариантов.

Возможно, вы захотите использовать один из:

30 голосов
/ 06 апреля 2014

Я думаю, что альтернативой было бы:

  • использовать такой инструмент, как SoapUI (http://www.soapui.org) для записи входных и выходных сообщений XML
  • использовать запрос узла(https://github.com/mikeal/request) для формирования входного xml-сообщения для отправки (POST) запроса веб-службе (обратите внимание, что стандартные механизмы создания шаблонов javascript, такие как ejs (http://embeddedjs.com/) или усы (https://github.com/janl/mustache.js)), могутздесь) и, наконец,
  • использовать анализатор XML для десериализации данных ответов на объекты JavaScript

Да, это довольно грязный и низкоуровневый подход, но он должен работать без проблем

16 голосов
/ 29 августа 2017

Если node-soap не работает для вас, просто используйте модуль node request и затем при необходимости конвертируйте xml в json.

Мой запрос не работал с node-soap, и нет поддержки этого модуля, кроме платной поддержки, которая была за пределами моих ресурсов.Поэтому я сделал следующее:

  1. скачал SoapUI на мою Linux-машину.
  2. скопировал XML-файл WSDL в локальный файл
    curl http://192.168.0.28:10005/MainService/WindowsService?wsdl > wsdl_file.xml
  3. В SoapUI я зашел на File > New Soap project и загрузил свой wsdl_file.xml.
  4. . В навигаторе я развернул одну из служб, щелкнул правой кнопкой мыши запрос и нажал Show Request Editor.

Оттуда я могу отправить запрос и убедиться, что он работает, и я также могу использовать данные Raw или HTML, чтобы помочь мне построить внешний запрос.

Raw из SoapUI для моегозапрос

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

Я использовал вышеупомянутое для построения следующего 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);
14 голосов
/ 20 мая 2016

Самый простой способ, который я нашел, просто отправить необработанный XML в службу SOAP с использованием Node.js, это использовать http-реализацию Node.js.Это выглядит следующим образом.

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

Вы бы определили переменную xml как необработанный xml в виде строки.

Но если вы просто хотите взаимодействовать со службой SOAP черезNode.js и совершайте регулярные вызовы SOAP, в отличие от отправки необработанного XML, используйте одну из библиотек Node.js.Мне нравится node-soap .

13 голосов
/ 24 января 2017

Мне удалось использовать soap, wsdl и Node.js Вам нужно установить мыло с npm install soap

Создайте сервер узлов с именем server.js, который определит службу мыла, которая будет использоваться удаленным клиентом. Эта служба мыла рассчитывает индекс массы тела на основе веса (кг) и роста (м).

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

Затем создайте файл client.js, который будет использовать службу мыла, определяемую server.js. Этот файл предоставит аргументы для службы мыла и вызовет URL с портами и конечными точками службы 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);
      }
    });
  }
});

Ваш файл wsdl - это основанный на xml протокол для обмена данными, который определяет, как получить доступ к удаленному веб-сервису. Позвоните в ваш файл 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>

Надеюсь, это поможет

9 голосов
/ 21 февраля 2015

В зависимости от необходимого вам количества конечных точек, это может быть проще сделать вручную.

Я попробовал 10 библиотек "soap nodejs", я наконец-то сделал это вручную.

8 голосов
/ 17 апреля 2015

Я успешно использовал пакет «мыло» (https://www.npmjs.com/package/soap) на более чем 10 отслеживающих WebApis (Tradetracker, Bbelboon, Affilinet, Webgains, ...).

Обычно проблемы возникают из-за того, чтоПрограммисты не слишком разбираются в том, что нужно удаленному API для подключения или аутентификации.

Например, PHP автоматически пересылает файлы cookie из заголовков HTTP автоматически, но при использовании пакета 'node' его необходимо явно установить (дляэкземпляр от пакета «мыло-печенье») ...

5 голосов
/ 14 ноября 2015

Я использовал модуль net сети, чтобы открыть сокет для веб-службы.

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

Отправка запросов на мыло

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

Анализ ответа на мыло, я использовал модуль - 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();
        }
    }
});

Надеюсь, это кому-нибудь поможет

5 голосов
/ 28 июня 2014

Вы также можете посмотреть на easysoap npm - https://www.npmjs.org/package/easysoap или некоторые из них: https://nodejsmodules.org/tags/soap

https://nodejsmodules.org/pkg/express-soap2json

0 голосов
/ 26 мая 2019

Для тех, кто плохо знаком с SOAP и хочет получить быстрое объяснение и руководство, я настоятельно рекомендую эту классную статью .

Вы также можете использовать node-soap пакет , с этим простым учебным пособием .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...