sourcetip

Node.js: SOAP XML 웹 서비스를 사용하는 방법

fileupload 2023. 9. 10. 12:29
반응형

Node.js: SOAP XML 웹 서비스를 사용하는 방법

node.js로 SOAP XML 웹 서비스를 소비하는 가장 좋은 방법이 무엇인지 궁금합니다.

감사합니다!

선택의 여지가 별로 없으시군요.

다음 중 하나를 사용할 수 있습니다.

그 대안은 다음과 같습니다.

  • 비누와 같은 도구를 사용합니다.입력 및 출력 xml 메시지를 기록하기 위한 UI(http://www.soapui.org )
  • node request(https://github.com/mikeal/request) 를 사용하여 웹 서비스에 요청을 보낼 입력 xml 메시지를 형성합니다(POST). ejs(https://github.com/janl/mustache.js) 또는 콧수염(http://embeddedjs.com/) 과 같은 표준 자바스크립트 템플릿 메커니즘이 여기에 도움이 될 수 있음) 마지막으로
  • XML 파서를 사용하여 응답 데이터를 자바스크립트 객체에 대한 병렬화

네, 이것은 다소 더럽고 낮은 수준의 접근법이지만 문제없이 작동할 것입니다.

한다면node-soap당신한테 안 맞는 것 같아요, 그냥 사용하세요.node request모듈을 구성한 다음 필요한 경우 xml을 json으로 변환합니다.

내 요청이 작동하지 않았습니다.node-soap그 모듈에 대한 지원은 유료 지원 외에는 없습니다. 제 능력으로는 불가능했습니다.그래서 저는 다음과 같이 했습니다.

  1. 다운로드 받은 비누 리눅스 머신의 UI.
  2. WSDL xml을 로컬 파일로 복사했습니다.
    curl http://192.168.0.28:10005/MainService/WindowsService?wsdl > wsdl_file.xml
  3. .UI에서 나는 갔었습니다.File > New Soap project그리고 제 것을 올렸습니다.wsdl_file.xml.
  4. 중한 후 오른쪽 단추로 하고 에서 를 한 합니다 을 하고 으로 합니다 하고 을 으로 에서 Show Request Editor.

거기서부터 나는 요청을 보낼 수 있었고 그것이 작동했는지 확인할 수 있었고 또한 나는 사용할 수 있었습니다.Raw아니면HTML외부 요청을 구축하는 데 도움이 되는 데이터입니다.

비누에서 날것나의 요청을 위한 UI

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);

Node할 수 . 은 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이된를할일를할ye에 의해 정의된 soap 서비스를 소비할 파일server.jsSOAP의 및합니다. 이 파일은 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를 사용하여 raw XML을 SOAP 서비스로 보내는 가장 간단한 방법은 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로 정의했을 것입니다.

그러나 Node.js를 통해 SOAP 서비스와 상호 작용하고 raw xml을 전송하는 것이 아니라 정기적으로 SOAP 호출을 하려면 Node.js 라이브러리 중 하나를 사용합니다.는 노드-비누를 좋아합니다.

필요한 엔드포인트 수에 따라 수동으로 수행하는 것이 더 쉬울 수 있습니다.

나는 10개의 라이브러리 "soap nodejs"를 시도해 보았는데 마침내 수동으로 합니다.

  • node request(https://github.com/mikeal/request) 를 사용하여 웹 서비스에 요청을 보낼 입력 xml 메시지를 형성합니다(POST).
  • xml2j(https://github.com/Leonidas-from-XIV/node-xml2js )를 사용하여 응답을 구문 분석합니다.

저는 10개 이상의 추적 WebApis(Tradetracker, Bbelboon, Affilinet, Webgains 등)에서 "package" 패키지(https://www.npmjs.com/package/soap) 를 성공적으로 사용했습니다.

문제는 일반적으로 프로그래머들이 원격 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;
    }

soap 응답 구문 분석, module - 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 - https://www.npmjs.org/package/easysoap - 또는-를 볼 수도 있습니다.

https://www.npmjs.com/package/express-soap2json

Kim을 추가합니다.J의 솔루션: 추가할 수 있습니다.preserveWhitespace=true화이트스페이스 오류를 방지하기 위해서입니다.다음과 같은 경우:

soap.CreateClient(url,preserveWhitespace=true,function(...){

wsdlrdr을 사용할 수도 있습니다.EasySoap은 기본적으로 wsdlrdr을 몇 가지 추가적인 방법으로 다시 쓰는 것입니다.easy soap에는 wsdlrdr에서 사용할 수 있는 getNamespace 메서드가 없으므로 주의하십시오.

일회성 전환이 필요한 경우 https://www.apimatic.io/dashboard?modal=transform 을 통해 무료 계정을 만들어 사용할 수 있습니다(소속 없음, 저에게는 효과 있음).

만약 당신이 스웨거 2.0으로 변신한다면, 당신은 jslib을 만들 수 있습니다.

$ 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

접두사 - 네임스페이스와 함께 사용할 웹 서비스를 가지고 있었지만 노드-비누와 함께 사용할 수 없었습니다.

그래서 axios post 방법을 시도했습니다.

브라우저로 이동하여 axios: https://somewebservice.company.com.br/WCF/Soap/calc.svc?wsdl 에서 URL 정보를 붙여넣습니다.

원하는 Soap 작업 이름이 나타날 때까지 아래로 스크롤합니다.

soap operation name

그런 다음 작업 soapAction = "http://xyzxyz/xyz/ObtenerSaldoDeParcelaDeEmpestimo"를 복사합니다.

axiosCall 헤더에 저장합니다.

const axiosCall = require('axios')
const xml2js = require('xml2js')

let xml = `<soapenv:Envelope 
                xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
                xmlns:tem="http://pempuri.org/" 
                xmlns:ser="http://schemas.example.org/2004/07/MyServices.Model">
            
            <soapenv:Header/>
                <soapenv:Body>
                
                <tem:DocumentState>
                <tem:DocumentData>
                     <ser:ID>0658</ser:ID>
                     <ser:Info>0000000001</ser:Info>
               </tem:DocumentData>
               </tem:DocumentState>
                
                </soapenv:Body>
            </soapenv:Envelope>         

let url = 'https://somewebservice.company.com.br/WCF/Soap/calc.svc?wsdl'

axiosCall.post( url,
            xml,
            {
                headers: {
                    'Content-Type': 'text/xml',
                    SOAPAction: 'http://xyzxyzxyz/xyz/xyz/ObtenerSaldoDeParcelaDeEmprestimo'
                }
            })
            .then((response)=>{
                 // xml2js to parse the xml response from the server 
                 // to a json object and then be able to iterate over it.

                 xml2js.parseString(response.data, (err, result) => {
                    
                    if(err) {
                        throw err;
                    }
                    console.log(result)
                }
                                        
            })

                
            })
            .catch((error)=>{
                
                console.log(error)
                
            })

처음 하시는 분들을 위해.SOAP그리고 빠른 설명과 가이드를 원하신다면, 이 멋진 기사를 강력 추천합니다.

사용할 수도 있습니다.node-soap 패키지간단한 튜토리얼이 있습니다.

제 생각에는 nodejs로 SOAP API를 조회하는 것을 피하세요.

두 가지 대안:

  1. 당신이 SOAP API의 소유자라면 json을 잘 처리하기 때문에 xml과 json 요청을 모두 처리하도록 하세요.

  2. API 게이트웨이를 php로 구현합니다(php는 SOAP를 잘 처리하기 때문입니다).게이트웨이는 당신의 입력을 json으로 받은 후, SOAP API를 xml로 쿼리하고 xml 응답을 json으로 변환합니다.

이것은 나에게 매력처럼 작용합니다.

간곡한 부탁

https://www.npmjs.com/package/easy-soap-request

단도직입적인

언급URL : https://stackoverflow.com/questions/8655252/node-js-how-to-consume-soap-xml-web-service

반응형