ฉันสงสัยว่าอะไรคือวิธีที่ดีที่สุดในการใช้บริการเว็บ SOAP XML กับ node.js
ขอบคุณ!
ฉันสงสัยว่าอะไรคือวิธีที่ดีที่สุดในการใช้บริการเว็บ SOAP XML กับ node.js
ขอบคุณ!
คำตอบ:
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
ไฟล์นี้จะให้อาร์กิวเมนต์สำหรับบริการ soap และเรียก 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>
หวังว่าจะช่วยได้
วิธีที่ง่ายที่สุดที่ฉันพบในการส่ง 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 ) ในการติดตาม WebApis มากกว่า 10 รายการ (Tradetracker, Bbelboon, Affilinet, Webgains, ... )
ปัญหามักมาจากการที่โปรแกรมเมอร์ไม่ได้ตรวจสอบมากนักเกี่ยวกับสิ่งที่ API ระยะไกลต้องการเพื่อเชื่อมต่อหรือพิสูจน์ตัวตน
ตัวอย่างเช่น PHP ส่งคุกกี้ใหม่จากส่วนหัว HTTP โดยอัตโนมัติ แต่เมื่อใช้แพ็คเกจ 'โหนด' จะต้องตั้งค่าอย่างชัดเจน (เช่นแพ็คเกจ 'soap-cookie') ...
ฉันใช้โมดูลโหนดเน็ตเพื่อเปิดซ็อกเก็ตไปยังบริการเว็บ
/* 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();
}
}
});
หวังว่ามันจะช่วยใครบางคน
นอกจากนี้คุณยังอาจมอง NPM easysoap - การhttps://www.npmjs.org/package/easysoap หรือ
การเพิ่มลงในโซลูชันของ Kim .J : คุณสามารถเพิ่มpreserveWhitespace=true
เพื่อหลีกเลี่ยงข้อผิดพลาดของช่องว่าง แบบนี้:
soap.CreateClient(url,preserveWhitespace=true,function(...){
คุณสามารถใช้ wsdlrdr ได้ด้วย EasySoap นั้นเขียนใหม่โดยทั่วไปของ wsdlrdr ด้วยวิธีการพิเศษบางอย่าง ระวังว่า easysoap ไม่มีเมธอด getNamespace ซึ่งมีอยู่ที่ wsdlrdr
หากคุณต้องการเพียงการแปลงครั้งเดียว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