Ws.js: 一个用于 Node.js 的 Ws-* 实现





5.00/5 (1投票)
Ws.js 是一个 Node.js 模块,允许使用 soap web 服务,这些服务利用 ws-* 标准(ws-security, mtom 等)。
介绍
Node.js 是编写可扩展服务器应用程序的绝佳平台。 其中一些应用程序需要与现有的 Web 服务通信。 只要这些服务是基于 Rest 的,这就不是问题 - Rest 服务在 node 中是一等公民。 如果我们需要使用 soap web 服务,我们可以快速搜索一下以找到 node-soap,或者我们可以决定自己手工构建 soap 信封。 真正的挑战是当 node 需要使用利用 WS-* 标准(WS-Security、MTOM 等)的 soap 服务时。 几个月前,当我遇到这种情况时,我找不到任何模块可以提供帮助。 这就是我决定构建 Ws.js 的原因。
使用代码
1. 首先,您必须安装 Ws.js 模块:
npm install ws.js
2. 现在编写您的代码:
var ws = require('ws.js')
, Http = ws.Http
, Security = ws.Security
, UsernameToken = ws.UsernameToken
var request = '<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/">' +
'<Header />' +
'<Body>' +
'<EchoString xmlns="http://tempuri.org/">' +
'<s>123</s>' +
'</EchoString>' +
'</Body>' +
'</Envelope>'
var ctx = { request: request
, url: "http://service/security"
, action: "http://tempuri.org/EchoString"
, contentType: "text/xml"
}
var handlers = [ new Security({}, [new UsernameToken({username: "yaron", password: "1234"})])
, new Http()
]
ws.send(handlers, ctx, function(ctx) {
console.log("response: " + ctx.response);
})
让我们分析一下这个例子。 以下代码导入相关的模块:
var ws = require('ws.js')
, Http = ws.Http
, Security = ws.Security
, UsernameToken = ws.UsernameToken
接下来的几行定义了 soap 信封和一些必要的信息,例如 url。 请注意,我们需要带外构建 soap - Ws.js 不是 soap 引擎。 然而,这通常很容易,因为我们通常有一个可用的 soap 示例。
var request = '<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/">' +
'<Header />' +
'<Body>' +
'<EchoString xmlns="http://tempuri.org/">' +
'<s>123</s>' +
'</EchoString>' +
'</Body>' +
'</Envelope>'
var ctx = { request: request
, url: "http://service/security"
, action: "http://tempuri.org/EchoString"
, contentType: "text/xml"
}
接下来的几行是 ws-* 使用的核心。 我们定义了要在请求中使用的协议。 此特定请求使用 ws-security 标准并将其配置为发送用户名令牌。
var handlers = [ new Security({}, [new UsernameToken({username: "yaron", password: "1234"})])
, new Http()
]
最后,这段代码发送请求(使用指定的协议)并处理响应。
ws.send(handlers, ctx, function(ctx) {
console.log("response: " + ctx.response);
})
生成的 soap 如下所示:
<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<Header>
<o:Security>
<u:Timestamp>
<u:Created>2012-02-26T11:03:40Z</u:Created>
<u:Expires>2012-02-26T11:08:40Z</u:Expires>
</u:Timestamp>
<o:UsernameToken>
<o:Username>yaron</o:Username>
<o:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">1234</o:Password>
</o:UsernameToken>
</o:Security>
</Header>
<Body>
<EchoString xmlns="http://tempuri.org/">
<s>123</s>
</EchoString>
</Body>
MTOM 示例
发送 MTOM 附件非常相似。 我们只需要指定要发送的文件以及它对应的 soap 元素的路径:
//add attachment to the soap request ws.addAttachment(ctx, "request", "//*[local-name(.)='File1']", "me.jpg", "image/jpeg") var handlers = [ new Mtom() , new Http() ];
完整的示例在这里。
支持的协议
目前 Ws.js 支持以下协议:
- MTOM
- WS-Security(仅用户名令牌)
- WS-Addressing(所有版本)
- HTTP(S)
幕后花絮
Ws.js 使用职责链设计模式来调用不同的协议。 这是一个可扩展的模式,因此任何人都可以添加新的协议实现。 虽然这是 soap 堆栈的已知模式,但在 javascript 中实现它可能会有点棘手。 关键是每个处理程序都有一个 send() 和一个 receive() 方法。 发送实际上将控制权传递给下一个处理程序。 我们给那个处理程序一个回调方法。 该回调将调用我们的 receive(),传递给它上下文和我们得到的原始回调(下游处理程序对此一无所知)。 最好看看代码:
SecurityHandler.prototype.send = function(ctx, callback) {
var self = this
//actual logic here...
this.next.send(ctx, function(ctx) {
self.receive(ctx, callback)
})
}
SecurityHandler.prototype.receive = function(ctx, callback) {
//optionally post processing here...
callback(ctx)
}
var s = new SecurityHandler()
s.next = new HttpHandler()
s.send(ctx, function(ctx) {...})
与许多 node 应用程序一样,Ws.js 也使用了一些外部模块。 它特别依赖于强大的 xml 处理库。 正如我在这里指出的那样,找到一个基于 dom 的 node.js xml 解析器,它可以在 windows 上工作,这并非易事。 我最终找到了 xmldom 和 xpath.js。
Ws.js 使用的其他值得注意的库是 node-formidable 和 node-bufferjs,它们在 mime 解析的上下文中很有帮助。
Ws.js 的未来
Ws.js 是一个不断发展的框架。 对于未来的版本,我计划添加更高级的安全标准,例如 X.509 数字签名和加密。 如果您有任何特殊要求,请从我的博客发送电子邮件给我。 如果您想提供帮助,请随时在 github 上 fork Ws.js - 这是发展 Ws.js 的最快方式。
更多信息
查看项目 github 页面
查看我的博客
从我的博客给我发邮件