使用Node.js 創建WebService服務端
最近幾天任務是用node.js去對接第三方的OA系統,對方OA系統屬於太古老的代碼了,還在使用WebService,用node.js調用WebService 很簡單,用soap模塊調用即可,網上已經有很多教程
但是當Node.js提供一個接口,供對方的webService調用,在網上找到對應教程。
- 難點:如何解析對方用soap調用該接口,獲取參數,
- 方式1:可以自己實現xml的解析
- 方式2:調用soap模塊
在實驗多次之後終於解決該問題
npm install soap
- 閱讀官方test代碼。
server-test
// 服務端代碼:
var soap = require('soap');
var fs = require('fs'),
http = require('http'),
lastReqAddress;
var test = {};
test.wsdl = fs.readFileSync('stockquote.wsdl', 'utf8');
test.server = null;
test.service = {
StockQuoteService: {
StockQuotePort: {
GetLastTradePrice: function(args, cb, soapHeader) {
if (soapHeader)
return { price: soapHeader.SomeToken };
if (args.tickerSymbol === 'trigger error') {
throw new Error('triggered server error');
} else if (args.tickerSymbol === 'Async') {
return cb({ price: 19.56 });
} else if (args.tickerSymbol === 'Promise Error') {
return new Promise((resolve, reject) => {
reject(new Error('triggered server error'));
});
} else if (args.tickerSymbol === 'Promise') {
return new Promise((resolve) => {
resolve({ price: 13.76 });
});
} else if (args.tickerSymbol === 'SOAP Fault v1.2') {
throw {
Fault: {
Code: {
Value: "soap:Sender",
Subcode: { value: "rpc:BadArguments" }
},
Reason: { Text: "Processing Error" }
}
};
} else if (args.tickerSymbol === 'SOAP Fault v1.1') {
throw {
Fault: {
faultcode: "soap:Client.BadArguments",
faultstring: "Error while processing arguments"
}
};
} else {
return { price: 19.56 };
}
},
SetTradePrice: function(args, cb, soapHeader) {
},
IsValidPrice: function(args, cb, soapHeader, req) {
lastReqAddress = req.connection.remoteAddress;
var validationError = {
Fault: {
Code: {
Value: "soap:Sender",
Subcode: { value: "rpc:BadArguments" }
},
Reason: { Text: "Processing Error" },
statusCode: 500
}
};
var isValidPrice = function() {
var price = args.price;
if(isNaN(price) || (price === ' ')) {
return cb(validationError);
}
price = parseInt(price, 10);
var validPrice = (price > 0 && price < Math.pow(10, 5));
return cb(null, { valid: validPrice });
};
setTimeout(isValidPrice, 10);
}
}
}
};
test.server = http.createServer(function(request,response) {
response.end('404: Not Found: ' + request.url);
});
test.server.listen(15099, null, null, function() {
test.soapServer = soap.listen(test.server, '/stockquote', test.service, test.wsdl);
test.baseUrl = 'http://' + test.server.address().address + ":" + test.server.address().port;
if (test.server.address().address === '0.0.0.0' || test.server.address().address === '::') {
test.baseUrl = 'http://127.0.0.1:' + test.server.address().port;
}
})
對應的wsdl代碼,我是直接複製官方的wsdl,
<?xml version="1.0"?>
<wsdl:definitions name="StockQuote"
targetNamespace="http://example.com/stockquote.wsdl"
xmlns:tns="http://example.com/stockquote.wsdl"
xmlns:xsd1="http://example.com/stockquote.xsd"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
<wsdl:types>
<xsd:schema targetNamespace="http://example.com/stockquote.xsd" xmlns:xsd="http://www.w3.org/2000/10/XMLSchema">
<xsd:element name="TradePriceRequest">
<xsd:complexType>
<xsd:all>
<xsd:element name="tickerSymbol" type="string"/>
</xsd:all>
</xsd:complexType>
</xsd:element>
<xsd:element name="TradePrice">
<xsd:complexType>
<xsd:all>
<xsd:element name="price" type="float"/>
</xsd:all>
</xsd:complexType>
</xsd:element>
<xsd:element name="TradePriceSubmit">
<xsd:complexType>
<xsd:all>
<xsd:element name="tickerSymbol" type="string"/>
<xsd:element name="price" type="float"/>
</xsd:all>
</xsd:complexType>
</xsd:element>
<xsd:element name="valid" type="boolean"/>
</xsd:schema>
</wsdl:types>
<wsdl:message name="GetLastTradePriceInput">
<wsdl:part name="body" element="xsd1:TradePriceRequest"/>
</wsdl:message>
<wsdl:message name="GetLastTradePriceOutput">
<wsdl:part name="body" element="xsd1:TradePrice"/>
</wsdl:message>
<wsdl:message name="SetTradePriceInput">
<wsdl:part name="body" element="xsd1:TradePriceSubmit"/>
</wsdl:message>
<wsdl:message name="IsValidPriceInput">
<wsdl:part name="body" element="xsd1:TradePrice"/>
</wsdl:message>
<wsdl:message name="IsValidPriceOutput">
<wsdl:part name="body" element="xsd1:valid"/>
</wsdl:message>
<wsdl:portType name="StockQuotePortType">
<wsdl:operation name="GetLastTradePrice">
<wsdl:input message="tns:GetLastTradePriceInput"/>
<wsdl:output message="tns:GetLastTradePriceOutput"/>
</wsdl:operation>
<wsdl:operation name="SetTradePrice">
<wsdl:input message="tns:SetTradePriceInput"/>
</wsdl:operation>
<wsdl:operation name="IsValidPrice">
<wsdl:input message="tns:IsValidPriceInput"/>
<wsdl:output message="tns:IsValidPriceOutput"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="StockQuoteSoapBinding" type="tns:StockQuotePortType">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="GetLastTradePrice">
<soap:operation soapAction="http://example.com/GetLastTradePrice"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="SetTradePrice">
<soap:operation soapAction="http://example.com/SetTradePrice"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
</wsdl:operation>
<wsdl:operation name="IsValidPrice">
<soap:operation soapAction="http://example.com/IsValidPrice"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="StockQuoteService">
<wsdl:port name="StockQuotePort" binding="tns:StockQuoteSoapBinding">
<soap:address location="http://localhost:15099/stockquote"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
用戶端調用
var soap = require('soap');
var url = 'http://127.0.0.1:15099/stockquote?wsdl';
//使用soap,根據wsdl地址創建客戶端
soap.createClient(url,function(err,client){
console.log(client)
if(err){
console.log(err);
}
//返回一個客戶端,並且傳參調用Java的接口,接收返回的數據
client.GetLastTradePrice({ tickerSymbol: 'Async'},function(error,result){
//打印接收到的數據
console.log(result);
});
})