Tôi tự hỏi đâu là cách tốt nhất để sử dụng dịch vụ web SOAP XML với node.js
Cảm ơn!
Tôi tự hỏi đâu là cách tốt nhất để sử dụng dịch vụ web SOAP XML với node.js
Cảm ơn!
Câu trả lời:
Bạn không có nhiều lựa chọn.
Có thể bạn sẽ muốn sử dụng một trong số:
node-soap
)sudo apt-get install libexpat1-dev
Tôi nghĩ rằng một giải pháp thay thế sẽ là:
Có, đây là một cách tiếp cận khá bẩn và cấp thấp nhưng nó sẽ hoạt động mà không có vấn đề gì
Nếu node-soap
không hiệu quả với bạn, chỉ cần sử dụng node
request
mô-đun và sau đó chuyển đổi xml thành json nếu cần.
Yêu cầu của tôi không hoạt động node-soap
và không có hỗ trợ nào cho mô-đun đó ngoài hỗ trợ trả phí, vượt quá tài nguyên của tôi. Vì vậy, tôi đã làm như sau:
curl http://192.168.0.28:10005/MainService/WindowsService?wsdl > wsdl_file.xml
File > New Soap project
và tải lên của mình wsdl_file.xml
.Show Request Editor
.Từ đó, tôi có thể gửi một yêu cầu và đảm bảo rằng nó hoạt động và tôi cũng có thể sử dụng Raw
hoặc HTML
dữ liệu để giúp tôi xây dựng một yêu cầu bên ngoài.
Nguyên từ SoapUI cho yêu cầu của tôi
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 từ 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>
Tôi đã sử dụng phần trên để xây dựng phần sau 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);
Tôi đã quản lý để sử dụng xà phòng, wsdl và Node.js Bạn cần cài đặt xà phòng với npm install soap
Tạo một máy chủ nút có tên server.js
sẽ xác định dịch vụ xà phòng sẽ được sử dụng bởi một máy khách từ xa. Dịch vụ xà phòng này tính Chỉ số khối cơ thể dựa trên cân nặng (kg) và chiều cao (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);
Tiếp theo, tạo một client.js
tệp sẽ sử dụng dịch vụ xà phòng được xác định bởi server.js
. Tệp này sẽ cung cấp các đối số cho dịch vụ xà phòng và gọi url với các cổng dịch vụ và điểm cuối của 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);
}
});
}
});
Tệp wsdl của bạn là một giao thức dựa trên xml để trao đổi dữ liệu xác định cách truy cập dịch vụ web từ xa. Gọi tệp wsdl của bạnbmicalculator.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>
Hy vọng nó giúp
Cách đơn giản nhất mà tôi tìm thấy để chỉ gửi XML thô đến dịch vụ SOAP bằng Node.js là sử dụng triển khai http Node.js. Nó trông như thế này.
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();
Bạn đã định nghĩa biến xml là xml thô ở dạng một chuỗi.
Nhưng nếu bạn chỉ muốn tương tác với một dịch vụ SOAP qua Node.js và thực hiện các cuộc gọi SOAP thông thường, thay vì gửi xml thô, hãy sử dụng một trong các thư viện Node.js. Tôi thích xà phòng nút .
Tùy thuộc vào số lượng điểm cuối bạn cần, có thể dễ dàng hơn để làm điều đó theo cách thủ công.
Tôi đã thử 10 thư viện "soap nodejs". Cuối cùng thì tôi cũng làm được theo cách thủ công.
Tôi đã sử dụng thành công gói "xà phòng" ( https://www.npmjs.com/package/soap ) trên hơn 10 WebApis theo dõi (Tradetracker, Bbelboon, Affilinet, Webgains, ...).
Các vấn đề thường đến từ thực tế là các lập trình viên không điều tra nhiều về những gì API từ xa cần để kết nối hoặc xác thực.
Ví dụ: PHP tự động gửi lại cookie từ các tiêu đề HTTP, nhưng khi sử dụng gói 'nút', nó phải được đặt rõ ràng (ví dụ: bằng gói 'soap-cookie') ...
Bạn cũng có thể xem easysoap npm - https://www.npmjs.org/package/easysoap -hoặc một số trong số này: https://nodejsmodules.org/tags/soap
Tôi đã sử dụng mô-đun node net để mở một ổ cắm cho dịch vụ 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);
}
});
Gửi yêu cầu xà phòng
/* 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;
}
Phân tích cú pháp xà phòng phản hồi, tôi đã sử dụng mô-đun - 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();
}
}
});
Hy vọng nó sẽ giúp ai đó
Thêm vào giải pháp của Kim .J : bạn có thể thêm preserveWhitespace=true
để tránh lỗi Khoảng trắng. Như thế này:
soap.CreateClient(url,preserveWhitespace=true,function(...){
Bạn cũng có thể sử dụng wsdlrdr. EasySoap về cơ bản là viết lại wsdlrdr với một số phương thức bổ sung. Hãy cẩn thận rằng easysoap không có phương thức getNamespace có sẵn tại wsdlrdr.
Nếu bạn chỉ cần chuyển đổi một lần, https://www.apimatic.io/dashboard?modal=transform cho phép bạn thực hiện việc này bằng cách tạo một tài khoản miễn phí (không có liên kết, nó chỉ hoạt động với tôi).
Nếu bạn biến thành Swagger 2.0, bạn có thể tạo js lib với
$ 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