Узел.js: как использовать веб-службу SOAP XML



интересно, каков наилучший способ использования веб-службы SOAP XML с узлом.js



спасибо!

1271   11  

11 ответов:

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

вы, вероятно, захотите использовать один из:

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

  • используйте такой инструмент, как 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

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

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

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-сервисом через узел.js и регулярные вызовы SOAP, в отличие от отправки необработанного xml, используют один из узлов.библиотеки js. Мне нравится узел-мыло.

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

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

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

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

ваш файл 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>

надеюсь, что это помогает

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

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

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

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

  1. загрузить SoapUI на моей машине с Linux.
  2. скопировал WSDL xml в локальный файл
    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> 

я использовал выше, чтобы построить после noderequest:

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

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

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

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

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

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

я использовал модуль node 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

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

разбор ответа soap, я использовал модуль-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: вы можете добавить preserveWhitespace=true для того чтобы избежать ошибки, пробелы. Вот так:

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

вы также можете использовать wsdlrdr. EasySoap в основном переписывает wsdlrdr с некоторыми дополнительными методами. Будьте осторожны, что easysoap не имеет getNamespace метод, который доступен в wsdlrdr.

Comments

    Ничего не найдено.