40、Web服务与REST架构:安全、消息传递、事务及Ajax应用解析

Web服务与REST架构:安全、消息传递、事务及Ajax应用解析

1. 身份联合与安全概念

身份联合允许第三方对身份信任进行中介。以旅行社为例,它能验证某人是否为其客户的员工,这可能会影响计费和折扣。在安全概念的规范和部署方面,基于SOAP的协议比原生HTTP协议表现更好。不过,这并不意味着HTTP协议无法弥补差距,也不意味着不能将SOAP的安全特性移植到HTTP上。目前,SOAP有许多HTTP所没有的安全相关特性,在实现如旅行代理这样的应用时,这些特性很有用。需要注意的是,这些安全领域并非业余者可以轻易涉足的,个人不应独自尝试为HTTP添加新的安全概念。

资源导向的替代方案则强调,应用的安全性取决于其最薄弱的环节。例如,若仅对信用卡号进行传输加密,却将其简单存储在数据库中,这只会让攻击者将目标转向数据库。安全视角应涵盖整个系统,而非仅关注网络传输的数据。WS - Security规范并非保障数据安全的唯一工具,HTTPS(即传输层安全[TLS],也称为安全套接层[SSL])在实践中已被证明足以保障信用卡信息在网络传输中的安全。XML签名和加密的使用也不限于WS - *相关标准,Atom联合格式标准的第5节展示了如何在Atom文档中使用这些特性,S3也在第3章中展示了如何实现请求签名和访问控制。这些安全方面在RESTful资源导向服务中是可行的,且已得到应用,但目前还未得到广泛推广。资源导向架构的优势在于其简单性和一致性,在构建安全应用时,复杂性和大量接口并非优势。

2. 可靠消息传递

WS - ReliableMessaging标准旨在为应用提供消息传递的保证,如最多一次(AtMostOnce)、至少一次(AtLeastOnce)、恰好一次(ExactlyOnce)或按顺序(InOrder)传递。它定义了一些新的头部信息(即信封上的“贴纸”)来跟踪序列标识符和消息编号,并包含一些重试逻辑。

在这方面,基于SOAP的协议在规范和实现上比原生HTTP更先进。但HTTP在某些情况下并不需要这些额外的“贴纸”。因为几乎所有的HTTP方法都是幂等的,如GET、HEAD、PUT或DELETE操作,如果操作未成功或不确定是否成功,只需重试请求即可。对于幂等操作,最多一次、至少一次和恰好一次传递没有区别。要实现按顺序传递,只需按顺序发送消息,并确保每条消息都能成功发送。唯一非幂等的方法是POST,而SOAP使用的正是POST方法,它通过定义额外的“贴纸”来解决可靠传递问题。在RESTful应用中,若要实现所有操作的可靠消息传递,建议实现“POST Once Exactly”或完全避免使用POST方法。WS - ReliableMessaging标准主要针对RESTful Web服务未涉及的复杂场景,如消息通过多种协议路由到目的地,或源和目的地都是间歇性访问网络的手机。

3. 事务处理

事务的概念简单,但在分布式环境中实现却极具挑战性。例如,将50美元从银行A转移到银行B,整个操作必须要么成功,要么失败。银行A和银行B相互竞争,各自提供独立的Web服务,理想情况是银行A扣款且银行B入账,或者什么都不发生,不希望出现只扣款不入账或只入账不扣款的情况。

事务处理有两种基本方法。WS - AtomicTransaction标准规定了一种常见的算法——两阶段提交。一般来说,这种方法仅适用于相互信任的各方之间,它易于实现,且在现有产品范围内,因此应用最为广泛。另一种方法由WS - BusinessActivity定义,它更贴近实际业务操作。例如,存入一张外国银行的支票时,银行可能会暂时冻结资金,并向外国银行寻求确认。若在冻结期内发现问题,银行会回滚交易;否则,接受支票。若在交易完成后发现问题,银行会创建一个补偿交易来撤销存款。这种方法的重点在于以可审计的方式纠正错误,而非仅仅防止错误发生。

在原生HTTP应用中,很少有能达到这种规范和部署水平的事务处理机制,通常也不需要。在某些情况下,可以将事务作为资源暴露来实现事务系统,若多个Web服务支持这种事务处理,可在其上添加一些基础设施,通过RESTful两阶段提交进行协调。但两阶段提交需要对所协调的服务有一定的控制权和信任度,当需要与竞争银行合作时,这种方法并不适用。SOA架构师认为两阶段提交一般不适用于基于Web服务的交互,对于RESTful Web服务也是如此。当无法控制所协调的服务时,建议使用异步操作来实现WS - BusinessActivity背后的思想。

4. BPEL、ESB和SOA

在上述基础上,还有一些在大型Web服务领域存在争议的概念。

Business Process Execution Language(BPEL)是一种XML语法,可用于描述跨多个参与方的业务流程,这些流程可通过软件和Web服务自动编排。Enterprise Service Bus(ESB)的定义各不相同,但通常包括Web服务请求的发现、负载均衡、路由、桥接、转换和管理等功能。这通常会导致操作与开发分离,使两者更简单易管理。然而,BPEL和ESB的缺点是它们往往会增加与通用第三方中间件的耦合度和依赖性。其优点是在中间件方面有多种选择,从支持良好的开源产品到知名的专有供应商提供的产品都有。

Service - Oriented Architecture(SOA)是一个定义最不明确的术语。有时关于SOA的讨论声称它涵盖了所有REST/HTTP应用,但最终焦点往往会转向本章所描述的大型Web服务标准。不过,SOA的一个值得注意的方面是,目前许多分布式编程方法侧重于远程过程调用,试图使其尽可能接近本地过程调用。而SOA将焦点重新放回接口,特别是跨越机器边界的接口。机器边界通常与信任边界相关,也是消息可靠性容易出现问题的地方,因此应该对其进行研究,而不是将其抽象掉。SOA的其他方面与服务的技术架构无关,可在资源导向环境、远程过程调用服务环境或异构环境中实现,例如“治理”涉及审计和政策合规性,这些“政策”可以是从政府法规到架构原则的任何内容。

5. 结论

REST和Web服务都已成为热门词汇,但很多人对它们的理解并不深入。本章旨在消除一些误解,展示了SOAP带来的价值有限,而WSDL带来的复杂性过高,同时也介绍了资源导向的替代方案。在选择时,如果需要本章中描述的某些仅在SOAP信封上可用的特性,从一开始就选择SOAP路径可能是个不错的基础。另一种选择是采用轻量级方法,遵循“你不会需要它”(YAGNI)原则,仅添加实际需要的功能。若最终发现需要大型Web服务才能提供的某些特性,可将XML表示包装在SOAP信封中,或挑选所需的特性并移植到HTTP头部。鉴于Web已被证明的可扩展性,从简单开始通常是一个安全的选择。

6. Ajax应用作为REST客户端

Ajax应用在过去几年中非常热门,但很多人对其定义并不清楚。正式定义为:Ajax应用是在Web浏览器中运行的Web服务客户端。例如,JavaScript表单验证器和Flash图形演示虽然在浏览器中运行,但它们不进行程序化的HTTP请求,因此不是Ajax应用;而第2章和第3章中编写的独立客户端不在浏览器中运行,也不是Ajax应用。以Gmail为例,登录后可以看到浏览器向mail.google.com的Web服务发送后台请求,并使用新数据更新网页,这正是Web服务客户端的行为。即使Gmail Web服务没有面向公众的名称,且仅供Gmail网页使用,但它仍然是一个Web服务,有像libgmail这样的库可以作为非Ajax客户端访问Gmail Web服务。

7. 从AJAX到Ajax

最初,Ajax被称为AJAX,是“Asynchronous JavaScript And XML”的缩写,但现在它只是一个普通词汇。这是因为AJAX所代表的含义并不一定准确,Ajax作为一种架构风格,不一定需要涉及JavaScript或XML。AJAX中的JavaScript实际上指的是任何能在浏览器端发起HTTP请求的语言,通常是JavaScript,但也可以是ActionScript(在Flash应用中运行)、Java(在小程序中运行)或特定浏览器语言(如Internet Explorer的VBScript)。XML实际上指的是Web服务发送的任何表示格式,只要浏览器端能够理解即可,常见的是XML,因为它易于浏览器解析,且Web服务倾向于提供XML表示,但JSON也很常见,还可以是HTML、纯文本或图像文件等。因此,开发者放弃了AJAX这个缩写,选择使用Ajax这个词,本书在讨论Ajax时,主要以JavaScript和XML为例,但实际上讨论的是一种应用架构。

8. Ajax架构

Ajax架构的工作流程如下:
1. 用户通过浏览器请求应用的主URI。
2. 服务器提供包含嵌入式脚本的网页。
3. 浏览器渲染网页,要么立即运行脚本,要么等待用户通过键盘或鼠标操作触发脚本的某个动作。
4. 脚本向服务器上的某个URI发起异步HTTP请求,用户在请求进行时可以进行其他操作,甚至可能意识不到请求正在发生。
5. 脚本解析HTTP响应,并使用数据修改用户的视图,这可能涉及使用DOM方法更改原始HTML页面的标签结构,或修改Flash应用或Java小程序中的显示内容。

从用户角度看,就好像GUI自己进行了修改。这种架构与客户端GUI应用类似,这也是为什么Ajax应用常被称赞为像桌面应用一样工作。与标准Web应用相比,标准Web应用的事件循环更简单,每次点击或表单提交都会导致整个视图刷新,浏览器获取新的HTML页面并构建全新的GUI元素;而Ajax应用的GUI可以逐步改变,这节省了带宽,减少了对最终用户的心理影响,应用看起来是逐步变化而非突然跳转。然而,Ajax应用的缺点是每个应用状态都使用相同的URI,即用户最初访问的那个URI,这破坏了可寻址性和无状态性。底层Web服务可能是可寻址和无状态的,但最终用户无法为特定状态添加书签,浏览器的“后退”按钮也无法正常工作,就像只暴露单个URI的SOAP + WSDL Web服务一样,该应用不再符合Web的特性。

9. del.icio.us示例

以del.icio.us社交书签应用的API为例,展示一个用JavaScript编写的Ajax客户端。该应用的用户界面使用纯HTML实现,与之前在命令行运行并将数据输出到标准输出的del.icio.us客户端不同。以下是该应用的具体代码和操作步骤:

首先是用户界面部分(Example 11 - 1):

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/transitional.dtd">
<!--delicious-ajax.html-->
<!--An Ajax application that uses the del.icio.us web service. This
     application will probably only work when saved as a local
     file. Even then, your browser's security policy might prevent it
     from running.-->
<html>
 <head>
  <title>JavaScript del.icio.us</title>
 </head> 
 <body>
  <h1>JavaScript del.icio.us example</h1>
  <p>Enter your del.icio.us account information, and I'll fetch and
  display your most recent bookmarks.</p>
  <form onsubmit="callDelicious(); return false;"> 
    Username: <input id="username" type="text" /><br /> 
    Password: <input id="password" type="password" /><br /> 
    <input type="submit" value="Fetch del.icio.us bookmarks"/>
  </form>
  <div id="message"></div>

  <ul id="links"></ul>

上述代码创建了一个HTML表单,用户可以输入del.icio.us账户信息,点击提交按钮将触发JavaScript函数 callDelicious 。同时,页面中有一个 div 标签用于显示消息,一个 ul 标签用于显示书签列表。

接着是 setMessage 函数(Example 11 - 2):

<script type="text/javascript">      
 function setMessage(newValue) { 
   message = document.getElementById("message"); 
   message.firstChild.textContent = newValue;
 }

该函数用于将给定的字符串放入 div 标签中,更新页面上的消息显示。

然后是 callDelicious 函数(Example 11 - 3和Example 11 - 4):

function callDelicious() { 
  try {
    if (netscape.security.PrivilegeManager.enablePrivilege)
      netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");
  } catch (e) { 
    alert("Sorry, browser security settings won't let this program run."); 
    return; 
  }
  var username = document.getElementById("username").value; 
  var password = document.getElementById("password").value;
  var links = document.getElementById("links"); 
  while (links.firstChild) 
    links.removeChild(links.firstChild) 
  setMessage("Please wait...");
  request = new XMLHttpRequest(); 
  request.open("GET", "https://api.del.icio.us/v1/posts/recent", true, 
               username, password);
  request.onreadystatechange = populateLinkList; 
  request.send(null);

此函数的操作步骤如下:
1. 尝试获取浏览器的权限以发送请求,如果权限获取失败,弹出警告框并终止程序。
2. 获取用户在表单中输入的账户信息。
3. 清空 ul 标签中的旧链接。
4. 在 div 标签中显示“请等待…”的消息。
5. 创建一个XMLHttpRequest对象,打开一个GET请求,请求的URL为 https://api.del.icio.us/v1/posts/recent ,并设置请求为异步,同时传入用户名和密码。
6. 设置 onreadystatechange 事件处理函数为 populateLinkList ,当请求状态改变时会调用该函数。
7. 发送请求。

最后是 populateLinkList 函数(Example 11 - 5):

function populateLinkList() { 
  if (request.readyState != 4) 
    return;
  setMessage("Request complete."); 
  if (netscape.security.PrivilegeManager.enablePrivilege) 
    netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");
  posts = request.responseXML.getElementsByTagName("post");
  setMessage(posts.length + " link(s) found:"); 
  for (var i = 0; i < posts.length; i++) { 
    post = posts[i]; 
    var link = document.createElement("a"); 
    var description = post.getAttribute('description'); 
    link.setAttribute("href", post.getAttribute('href'));
    link.appendChild(document.createTextNode(description));
    var li = document.createElement("li");
    li.appendChild(link);
    document.getElementById("links").appendChild(li);
  }
}

该函数的操作步骤如下:
1. 检查请求是否完成,如果未完成则返回。
2. 在 div 标签中显示“请求完成”的消息。
3. 再次尝试获取浏览器的权限。
4. 从响应的XML文档中获取所有的 post 标签。
5. 在 div 标签中显示找到的链接数量。
6. 遍历每个 post 标签,为每个标签创建一个链接,设置链接的 href 属性为标签的 href 属性值,设置链接的文本为标签的 description 属性值。
7. 将链接放入一个 li 标签中,并将 li 标签添加到 ul 标签中。

这个简单的程序展示了Ajax应用的优点和问题,如异步请求、局部更新页面等,但也存在可寻址性和无状态性被破坏的问题。通过这个示例,可以更好地理解Ajax应用在实际中的工作原理和实现方式。

Web服务与REST架构:安全、消息传递、事务及Ajax应用解析

10. 总结与对比

为了更清晰地对比不同技术和概念,下面通过表格进行总结:
| 技术概念 | 优点 | 缺点 | 适用场景 |
| — | — | — | — |
| SOAP | 具有丰富的安全特性和可靠消息传递机制,适用于复杂业务场景 | 复杂性高,与第三方中间件耦合度高 | 对安全和消息可靠性要求高,且信任关系明确的多方交互场景 |
| RESTful架构 | 简单、一致,具有良好的可扩展性 | 部分安全和事务处理机制需额外实现 | 对性能和简单性要求高,资源导向的应用场景 |
| BPEL | 可描述跨多方的业务流程,实现自动编排 | 增加与中间件的耦合度和依赖性 | 复杂业务流程的自动化编排场景 |
| ESB | 提供请求的发现、负载均衡等功能,分离操作与开发 | 增加与中间件的耦合度和依赖性 | 需要对Web服务请求进行集中管理和优化的场景 |
| Ajax | 实现异步请求,局部更新页面,提升用户体验 | 破坏可寻址性和无状态性 | 需要实现类似桌面应用交互体验的Web应用场景 |

11. 技术选择建议

在选择合适的技术时,需要综合考虑多个因素,以下是一些具体的建议:
- 安全需求 :如果对安全要求极高,如涉及金融交易等敏感信息,SOAP的安全特性可能更适合;如果安全需求相对较低,且追求简单性,RESTful架构结合HTTPS也能满足基本安全需求。
- 业务复杂度 :对于复杂的业务流程,涉及多方交互和事务处理,BPEL和ESB可以帮助实现自动化编排和管理;对于简单的资源操作,RESTful架构更为合适。
- 用户体验 :如果希望提供类似桌面应用的交互体验,减少页面刷新,Ajax是一个不错的选择;如果对用户体验要求不高,传统的Web应用架构也能满足需求。
- 可扩展性 :考虑到未来业务的增长和变化,RESTful架构的简单性和一致性使其更易于扩展;而SOAP和BPEL等技术在复杂场景下的扩展性可能会受到中间件和耦合度的限制。

12. 未来发展趋势

随着技术的不断发展,Web服务和REST架构也在不断演进。以下是一些可能的未来发展趋势:
- 融合发展 :不同技术之间可能会相互融合,取各自的优点,形成更强大的解决方案。例如,RESTful架构可能会借鉴SOAP的一些安全和事务处理机制,以提升其在复杂场景下的适用性。
- 轻量化和高效化 :未来的技术将更加注重轻量化和高效化,减少不必要的复杂性和资源消耗。例如,Ajax技术可能会进一步优化,解决可寻址性和无状态性的问题。
- 标准化和规范化 :随着Web服务的广泛应用,标准化和规范化将变得更加重要。相关的标准和规范将不断完善,以促进不同系统之间的互操作性和兼容性。

13. 实际应用案例分析

为了更好地理解上述技术在实际中的应用,下面通过一个具体案例进行分析。假设我们要开发一个在线旅游预订系统,该系统涉及用户信息管理、酒店预订、机票预订等多个业务模块。

  • 架构选择 :考虑到系统的复杂性和对性能的要求,采用RESTful架构作为基础架构。RESTful架构的简单性和一致性可以提高开发效率,同时便于系统的扩展和维护。
  • 安全实现 :对于用户信息和交易数据的安全,采用HTTPS协议进行传输加密,同时结合OAuth等认证机制,确保用户身份的合法性。
  • 事务处理 :在酒店预订和机票预订等涉及资金交易的业务模块中,采用异步操作和补偿交易的方式,实现类似WS - BusinessActivity的事务处理机制,确保交易的一致性和可靠性。
  • 用户体验 :使用Ajax技术实现异步请求和局部更新,提升用户在搜索、预订等操作时的交互体验,减少页面刷新带来的等待时间。

通过这个案例可以看出,在实际应用中,需要根据具体的业务需求和场景,综合运用不同的技术,以实现最佳的效果。

14. 技术实践建议

对于想要实践上述技术的开发者,以下是一些具体的建议:
- 学习基础知识 :首先要掌握Web服务、REST架构、JavaScript、XML等基础知识,了解它们的原理和应用场景。
- 实践项目 :通过实际项目来巩固所学知识,可以从简单的项目开始,逐步增加复杂度。例如,可以先开发一个简单的RESTful API,然后再结合Ajax技术实现一个Web应用。
- 参考开源项目 :参考优秀的开源项目,学习他人的设计思路和实现方法。例如,GitHub上有许多开源的RESTful API和Ajax应用,可以从中获取灵感。
- 持续学习 :技术在不断发展,需要持续学习和关注最新的技术动态,不断提升自己的技术水平。

15. 总结

本文详细介绍了Web服务和REST架构相关的多个重要概念,包括身份联合、可靠消息传递、事务处理、BPEL、ESB、SOA以及Ajax应用等。通过对这些概念的分析和对比,我们可以看到不同技术在不同场景下的优缺点。在实际应用中,需要根据具体的业务需求、安全要求、用户体验和可扩展性等因素,综合选择合适的技术。同时,随着技术的不断发展,我们也应该关注未来的发展趋势,不断学习和实践,以适应不断变化的技术环境。希望本文能够帮助读者更好地理解和应用这些技术,在实际开发中做出更明智的选择。

以下是一个mermaid格式的流程图,展示了Ajax应用的基本工作流程:

graph LR
    A[用户请求主URI] --> B[服务器提供含脚本网页]
    B --> C{用户操作触发脚本?}
    C -- 是 --> D[脚本发起异步HTTP请求]
    C -- 否 --> C
    D --> E{请求完成?}
    E -- 否 --> E
    E -- 是 --> F[脚本解析响应数据]
    F --> G[脚本修改用户视图]

通过这个流程图,可以更直观地理解Ajax应用的异步请求和局部更新机制。在实际开发中,开发者可以根据这个流程来实现具体的Ajax应用,提升用户体验。

同步定位地图构建(SLAM)技术为移动机器人或自主载具在未知空间中的导航提供了核心支撑。借助该技术,机器人能够在探索过程中实时构建环境地图并确定自身位置。典型的SLAM流程涵盖传感器数据采集、数据处理、状态估计及地图生成等环节,其核心挑战在于有效处理定位环境建模中的各类不确定性。 Matlab作为工程计算数据可视化领域广泛应用的数学软件,具备丰富的内置函数专用工具箱,尤其适用于算法开发仿真验证。在SLAM研究方面,Matlab可用于模拟传感器输出、实现定位建图算法,并进行系统性能评估。其仿真环境能显著降低实验成本,加速算法开发验证周期。 本次“SLAM-基于Matlab的同步定位建图仿真实践项目”通过Matlab平台完整再现了SLAM的关键流程,包括数据采集、滤波估计、特征提取、数据关联地图更新等核心模块。该项目不仅呈现了SLAM技术的实际应用场景,更为机器人导航自主移动领域的研究人员提供了系统的实践参考。 项目涉及的核心技术要点主要包括:传感器模型(如激光雷达视觉传感器)的建立应用、特征匹配数据关联方法、滤波器设计(如扩展卡尔曼滤波粒子滤波)、图优化框架(如GTSAMCeres Solver)以及路径规划避障策略。通过项目实践,参者可深入掌握SLAM算法的实现原理,并提升相关算法的设计调试能力。 该项目同时注重理论向工程实践的转化,为机器人技术领域的学习者提供了宝贵的实操经验。Matlab仿真环境将复杂的技术问题可视化可操作化,显著降低了学习门槛,提升了学习效率质量。 实践过程中,学习者将直面SLAM技术在实际应用中遇到的典型问题,包括传感器误差补偿、动态环境下的建图定位挑战以及计算资源优化等。这些问题的解决对推动SLAM技术的产业化应用具有重要价值。 SLAM技术在工业自动化、服务机器人、自动驾驶及无人机等领域的应用前景广阔。掌握该项技术不仅有助于提升个人专业能力,也为相关行业的技术发展提供了重要支撑。随着技术进步应用场景的持续拓展,SLAM技术的重要性将日益凸显。 本实践项目作为综合性学习资源,为机器人技术领域的专业人员提供了深入研习SLAM技术的实践平台。通过Matlab这一高效工具,参者能够直观理解SLAM的实现过程,掌握关键算法,并将理论知识系统应用于实际工程问题的解决之中。 资源来源于网络分享,仅用于学习交流使用,请勿用于商业,如有侵权请联系我删除!
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值