首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

延续、Web 开发和 Java 编程(3)

延续、Web 开发和 Java 编程(3)

Java 语言中的延续服务器Java 开发人员正在注意到基于延续的方式对构建 Web 框架的好处,但是 Java 语言不支持本机延续。如果您的语言不支持延续,那么就只有几种办法了:模拟延续、将延续添加到现有的语言中或者选用另一种语言。不同的 Java 框架(参见 )采用了不同的办法:
  • 模拟延续。 一些 Java 框架使用替代方法来捕获执行状态。Lakeshore 使用线程,Spring Web Flow 使用状态机(在本文后面还将进一步讨论 Web Flow)。
  • 选用另一种语言。 Java 虚拟机可以基于其他语言。Cocoon 2 通过 Rhino 采用这种方式,Rhino 是一种虚拟机,它支持 JavaScript,也支持 Java。
  • 实现延续。 Jetty 6 servlet 容器、RIFE 和 WebWork 采用这种方式。
模拟本机延续不一定非使用延续来捕获执行状态。暂停的线程和状态机都可以捕获执行状态。线程化方式简单地冻结并存储现有的线程。这种方式有一点儿受限制,因为它不提供无状态性能 —— 实际上是为每个用户使用一个单独的线程。
但是,状态机(state machine)是不错的延续方式。状态机是一种定义了状态之间的转换的程序。到目前为止,具有延续服务器特征的最流行的 Java 框架是 Spring 的 Web Flow。Web Flow 采用状态机形式对用户界面页面之间的导航进行建模。Web Flow 可以将程序流建模成 Java 对象,但是常常使用 XML 来描述程序流。请考虑清单 3 中来自 Web Flow 教程(参见 )的程序流表示:
清单 3. Web Flow 程序流表示
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE webflow PUBLIC "-//SPRING//DTD WEBFLOW//EN"
        "http://www.springframework.org/dtd/spring-webflow.dtd">
<webflow id="myFlow" start-state="displayForm">
    <view-state id="displayForm" view="form">
        <entry>
            <action bean="myFlowAction" method="setupForm"/>
        </entry>
        <transition on="submit" to="processSubmit">
            <action bean="myFlowAction" method="bindAndValidate"/>
        </transition>
    </view-state>
    <action-state id="processSubmit">
        <action bean="myFlowAction"/>
        <transition on="success" to="finish"/>
    </action-state>
         
    <end-state id="finish" view="success"/>
</webflow>




这个流程有三个核心状态:displayForm、processSubmit 和 finish。这个程序流定义了使机器从一个状态转换到下一个状态的动作。例如,submit 将状态从 displayForm 转换到 processSubmit。Web Flow 在典型的模型-视图-控制器级别上操作。可以使用许多不同的视图技术来显示表单。
当从一个状态转换到下一个状态时,框架自动捕获当前状态,包括所有实例变量。这样就可以获得与其他延续服务器一样的 Back 按钮支持和有状态编程模型。这种方式不使用本机延续,但是具有延续服务器的许多优点,还有其他一些优点:
  • 持久性。 尽管不能捕获整个调用堆栈,但是可以捕获当前执行状态,甚至可以持久存储当前状态。
  • 长期存活的程序流,比如工作流。 因为状态不依赖于给定的调用堆栈,所以这种方式对于长期工作流这样的东西更稳定。
  • 工具。 很容易为 XML 构建工具。
其他语言Cocoon 使用 Rhino,这是一种插入到 JVM 中的 JavaScript 虚拟机。Cocoon 控制器使用一个修改过的 Rhino 版本来表达延续,所以 Cocoon 允许用 Java 或 JavaScript 来表达控制器逻辑。请考虑清单 4 中来自 Cocoon 教程的应用程序(参见 ):
清单 4. 使用 Cocoon
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
try {
  if (operator == "plus")
    cocoon.sendPage("result.html", {result: a + b});
  else if (operator == "minus")
    cocoon.sendPage("result.html", {result: a - b});
  else if (operator == "multiply")
    cocoon.sendPage("result.html", {result: a * b});
  else if (operator == "divide")
    cocoon.sendPage("result.html", {result: a / b});
  else
    cocoon.sendPage("invalidOperator.html", {operator: operator});
}
catch (e) {
  cocoon.sendPage("error.html",
    {message: "Operation failed: " + e.toString()});
}




注意清单 4 中的 sendPage 方法。这个方法将一个页面发送给用户。这里没有支持 Back 按钮或者将用户数据保存到会话中所需的冗长代码 —— 这些都封装在 Cocoon 的框架中了。
实现延续RIFE 框架实现它自己的延续,而 WebWork 框架使用 RIFE 的延续实现。Jetty 6 也包含一个用 Java 编写的延续实现。清单 5 给出了一个来自 RIFE 教程的例子,这个例子是一个猜数字游戏:
清单 5. RIFE 示例
1
2
3
4
5
6
7
8
9
10
while (mGuess != answer) {
  print(template);
  pause();
  guesses++;
  if (answer < mGuess) {
    template.setBlock("indication", "lower");
  } else if (answer > mGuess).{
    template.setBlock("indication", "higher");
  }
}




在这个例子中,pause() 方法捕获延续并将模板发送回用户供操作。RIFE 使延续变得很简单,一般的 Web 开发人员也能够使用延续。
不远的将来您可以看到,延续是 Web 开发框架中一项真正的技术进步。利用这种方式,可以获得更高的生产效率。另外,因为采用直观的 Java 代码(而不是数百个互不相连的 servlet)来表达 Web 应用程序,应用程序更容易理解和维护。
Web 开发方面新的发展使延续方式变得越来越重要。Ajax 应用程序可以异步地获得 Web 页面的一小部分并将结果编织进现有的页面中,而不是用传统的请求/响应模型来获得整个 Web 页面。但是 Ajax 应用程序可能会迫使应用程序长期维持与用户的连接,这样应用程序才能进行响应并使状态跟踪代码比较容易编写。这种做法破坏了无状态编程的优势,因为需要为每个连接的用户占用一定的资源。有了延续,就可以在延续中保存状态并根据需要恢复状态。
在不远的将来,硬件的改进会使延续所增加的资源消耗变得无足轻重。如果不经过彻底的革新,Web 开发框架仍然会太复杂。Ajax 会使 Web 开发更加复杂。这些因素都会促使人们接受延续服务器。在两年内,大多数新的 Web 开发将会使用某种延续服务器或延续的模拟。
返回列表