node.js로 SOAP XML 웹 서비스를 사용하는 가장 좋은 방법이 무엇인지 궁금합니다.
감사!
node.js로 SOAP XML 웹 서비스를 사용하는 가장 좋은 방법이 무엇인지 궁금합니다.
감사!
답변:
sudo apt-get install libexpat1-dev
나는 대안이 될 것이라고 생각합니다.
예, 이것은 다소 더럽고 낮은 수준의 접근 방식이지만 문제없이 작동합니다.
경우 node-soap
당신을 위해 일을하지 않습니다, 단지 사용하는 node
request
모듈을하고 필요한 경우 다음 JSON으로 XML을 변환합니다.
내 요청이 작동 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)
SoapUI의 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>
위를 사용하여 다음을 빌드했습니다 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 및 Node.js를 사용했습니다. npm install soap
server.js
원격 클라이언트가 사용할 SOAP 서비스를 정의하는 라는 노드 서버를 작성하십시오 . 이 비누 서비스는 체중 (kg)과 키 (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);
다음으로에 client.js
정의 된 SOAP 서비스를 사용할 파일을 만듭니다 server.js
. 이 파일은 SOAP 서비스에 대한 인수를 제공하고 SOAP의 서비스 포트 및 엔드 포인트로 URL을 호출합니다.
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>
도움이되기를 바랍니다.
Node.js를 사용하여 SOAP 서비스에 원시 XML을 보내는 가장 간단한 방법은 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로 정의했을 것입니다.
그러나 원시 xml을 보내는 대신 Node.js를 통해 SOAP 서비스와 상호 작용하고 일반 SOAP 호출을 수행하려는 경우 Node.js 라이브러리 중 하나를 사용하십시오. 나는 node-soap을 좋아 합니다 .
필요한 엔드 포인트의 수에 따라 수동으로 수행하는 것이 더 쉬울 수 있습니다.
나는 10 개의 라이브러리 "soap nodejs"를 시도했다. 마침내 수동으로한다.
10 개 이상의 추적 WebApis (Tradetracker, Bbelboon, Affilinet, Webgains, ...)에서 "soap"패키지 ( https://www.npmjs.com/package/soap )를 성공적으로 사용했습니다 .
문제는 일반적으로 프로그래머가 연결 또는 인증을 위해 필요한 원격 API에 대해 많이 조사하지 않는다는 사실에서 발생합니다.
예를 들어 PHP는 HTTP 헤더에서 쿠키를 자동으로 재전송하지만 '노드'패키지를 사용할 때는 명시 적으로 설정해야합니다 (예 : 'soap-cookie'패키지) ...
easysoap npm- https : //www.npmjs.org/package/easysoap- 또는 다음 중 일부 : 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 요청 보내기
/* 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();
}
}
});
누군가에게 도움이되기를 바랍니다.
wsdlrdr도 사용할 수 있습니다. EasySoap은 기본적으로 몇 가지 추가 방법으로 wsdlrdr을 다시 작성합니다. easysoap에는 wsdlrdr에서 사용할 수있는 getNamespace 메소드가 없습니다.
일회성 변환이 필요한 경우 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