SOAP XML web hizmetini node.js ile tüketmenin en iyi yolunun ne olduğunu merak ediyorum
Teşekkürler!
SOAP XML web hizmetini node.js ile tüketmenin en iyi yolunun ne olduğunu merak ediyorum
Teşekkürler!
Yanıtlar:
O kadar çok seçeneğin yok.
Muhtemelen şunlardan birini kullanmak isteyeceksiniz:
node-soap
)sudo apt-get install libexpat1-dev
Sanırım bir alternatif:
Evet, bu oldukça kirli ve düşük seviyeli bir yaklaşım ama sorunsuz çalışmalı
İşinize node-soap
yaramazsa, node
request
modülü kullanın ve ardından gerekirse xml'yi json'a dönüştürün.
İsteğim çalışmıyordu node-soap
ve kaynaklarımın ötesinde ücretli desteğin ötesinde bu modül için destek yok. Ben de şunları yaptım:
curl http://192.168.0.28:10005/MainService/WindowsService?wsdl > wsdl_file.xml
File > New Soap project
ve kendimi yükledim wsdl_file.xml
.Show Request Editor
.Oradan bir istek gönderebilir ve çalıştığından emin olabilirim ve ayrıca harici bir istek oluşturmama yardımcı olması için Raw
veya HTML
verilerini kullanabilirim .
SoapUI'den isteğim için ham
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)
SoapUI'den 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>
Aşağıdakileri oluşturmak için yukarıdakileri kullandım 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);
Soap, wsdl ve Node.js kullanmayı başardım. npm install soap
server.js
Uzak bir istemci tarafından kullanılacak olan soap hizmetini tanımlayacak bir düğüm sunucusu oluşturun . Bu sabun servisi, ağırlık (kg) ve boy (m) temelinde Vücut Kitle İndeksini hesaplar.
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);
Ardından, client.js
tarafından tanımlanan sabun hizmetini tüketecek bir dosya oluşturun server.js
. Bu dosya, soap servisi için argümanlar sağlayacak ve url'yi SOAP'ın servis portları ve uç noktaları ile arayacaktır.
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 dosyanız, uzak bir web hizmetine nasıl erişileceğini tanımlayan, veri alışverişi için xml tabanlı bir protokoldür. Wsdl dosyanızı arayı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>
Umarım yardımcı olur
Node.js kullanarak bir SOAP hizmetine ham XML göndermenin bulduğum en basit yolu Node.js http uygulamasını kullanmaktır. Şuna benziyor.
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 değişkenini bir dize biçiminde ham xml olarak tanımlardınız.
Ancak, Node.js aracılığıyla bir SOAP hizmetiyle etkileşim kurmak ve ham xml göndermek yerine düzenli SOAP çağrıları yapmak istiyorsanız, Node.js kitaplıklarından birini kullanın. Düğüm sabunu severim .
İhtiyacınız olan uç nokta sayısına bağlı olarak, bunu manuel olarak yapmak daha kolay olabilir.
10 kitaplık "soap nodejs" denedim, sonunda elle yapıyorum.
"Soap" paketini ( https://www.npmjs.com/package/soap ) 10'dan fazla WebApis'te (Tradetracker, Bbelboon, Affilinet, Webgains, ...) başarıyla kullandım .
Sorunlar genellikle programcıların bağlanmak veya kimlik doğrulamak için hangi uzak API'ye ihtiyaç duyduğu konusunda fazla araştırma yapmamasından kaynaklanır.
Örneğin PHP, tanımlama bilgilerini HTTP üstbilgilerinden otomatik olarak yeniden gönderir, ancak 'düğüm' paketini kullanırken, açıkça ayarlanması gerekir (örneğin 'sabun-çerez' paketi ile) ...
Ayrıca easysoap npm - https://www.npmjs.org/package/easysoap -veya bunlardan bazılarına da bakabilirsiniz : https://nodejsmodules.org/tags/soap
Web servisine bir soket açmak için node net modülünü kullandım.
/* 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);
}
});
Sabun istekleri gönderin
/* 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;
}
Sabun yanıtını ayrıştır, modül kullandım - 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();
}
}
});
Umarım birine yardımcı olur
Kim .J'nin çözümüne ekleme : preserveWhitespace=true
Whitespace hatasını önlemek için ekleyebilirsiniz . Bunun gibi:
soap.CreateClient(url,preserveWhitespace=true,function(...){
Wsdlrdr'yi de kullanabilirsiniz. EasySoap, wsdlrdr'nin bazı ekstra yöntemlerle yeniden yazılmasıdır. Easysoap'un wsdlrdr'de bulunan getNamespace yöntemine sahip olmadığına dikkat edin.
Tek seferlik bir dönüşüme ihtiyacınız varsa, https://www.apimatic.io/dashboard?modal=transform bunu ücretsiz bir hesap oluşturarak yapmanıza izin verir (bağlantı yok, sadece benim için çalıştı).
Swagger 2.0'a dönüşürseniz, bir js lib yapabilirsiniz.
$ 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