Цікаво, який найкращий спосіб використовувати веб-службу SOAP XML із node.js
Дякую!
Цікаво, який найкращий спосіб використовувати веб-службу SOAP XML із node.js
Дякую!
Відповіді:
У вас не так багато варіантів.
Можливо, вам захочеться скористатися одним із:
node-soap
)sudo apt-get install libexpat1-dev
Я думаю, що альтернативою було б:
Так, це досить брудний і низькорівневий підхід, але він повинен працювати без проблем
Якщо у вас node-soap
не виходить, просто використовуйте node
request
модуль, а потім перетворіть xml на json, якщо це потрібно.
З моїм запитом не працювали, node-soap
і для цього модуля немає підтримки, крім платної підтримки, яка була за межами моїх ресурсів. Тож я зробив наступне:
curl http://192.168.0.28:10005/MainService/WindowsService?wsdl > wsdl_file.xml
File > New Soap project
і завантажив свій wsdl_file.xml
.Show Request Editor
.Звідти я міг відправити запит і переконатися, що він працює, а також міг використати дані Raw
або, HTML
щоб допомогти мені створити зовнішній запит.
Сирець із 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);
Мені вдалося використовувати мило, 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, який визначає спосіб доступу до віддаленої веб-служби. Зателефонуйте своєму файлу wsdlbmicalculator.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>
Сподіваюся, це допомагає
Найпростіший спосіб просто надіслати необроблений XML до SOAP-служби за допомогою Node.js - це використання Node.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 через Node.js і робити регулярні виклики SOAP, на відміну від надсилання необробленого xml, використовуйте одну з бібліотек Node.js. Мені подобається вузол-мило .
Залежно від кількості потрібних вам кінцевих точок може бути простіше зробити це вручну.
Я спробував 10 бібліотек "soap nodejs", нарешті, роблю це вручну.
Я успішно використав пакет "мило" ( https://www.npmjs.com/package/soap ) у більш ніж 10 веб-програмах для відстеження (Tradetracker, Bbelboon, Affilinet, Webgains, ...).
Зазвичай проблеми виникають внаслідок того, що програмісти не надто досліджують, що потрібно віддаленому API для підключення або автентифікації.
Наприклад, PHP автоматично перепродає файли cookie з заголовків HTTP, але при використанні пакету 'node' він повинен бути чітко встановлений (наприклад, пакетом 'soap-cookie') ...
Ви також можете подивитися на easysoap npm - https://www.npmjs.org/package/easysoap -or- деякі з них: https://nodejsmodules.org/tags/soap
Я використав модуль 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 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();
}
}
});
Сподіваюся, це комусь допомагає
Ви також можете використовувати wsdlrdr. EasySoap в основному переписує wsdlrdr за допомогою деяких додаткових методів. Будьте обережні, щоб у easysoap не було методу getNamespace, який доступний у wsdlrdr.
Тим, хто новачок у роботі SOAP
та бажає швидкого пояснення та керівництва, я настійно рекомендую цю дивовижну середню статтю .
Ви також можете використовувати node-soap
пакет , за допомогою цього простого підручника .
Якщо вам просто потрібна одноразова конверсія, https://www.apimatic.io/dashboard?modal=transform дозволяє це зробити, створивши безкоштовний акаунт (ніякої афіліації, це просто спрацювало у мене).
Якщо ви перетворюєтеся на Swagger 2.0, ви можете створити js lib за допомогою
$ 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