This page last changed on Sep 16, 2004 by vitorsouza.

第三课: 活动和结果

活动(Action)是程序执行的基本单元. 活动是一个注册在WebWork配置文件中用以响应某一请求的类. 在模型-视图-控制器方式中, 活动是控制器的一部分, 留给JSP页面的是他们最擅长的工作: 创建视图.

下面是在WenWork中创建活动的可能的步骤:

  1. 创建一个调用活动的JSP页面;
  2. 创建一个活动类;
  3. 创建一个处理结果的JSP页面;
  4. xwork.xml中注册活动.

本指南的第一个例子正是"Hello, WebWorld!". 下面的代码展示了含有一个活动配置信息的WebWork配置文件xwork.xml, 该活动注册在default包中.

xwork.xml:

<!DOCTYPE xwork PUBLIC "-//OpenSymphony Group//XWork 1.0//EN"
"http://www.opensymphony.com/xwork/xwork-1.0.dtd">

<xwork>
	<!-- Include webwork defaults (from WebWork JAR). -->
	<include file="webwork-default.xml" />
	
	<!-- Configuration for the default package. -->
	<package name="default" extends="webwork-default">
		<!-- Default interceptor stack. --> 
		<default-interceptor-ref name="defaultStack" /> 
		
		<!-- Action: Lesson 03: HelloWebWorldAction. --> 
		<action name="helloWebWorld" class="lesson03.HelloWebWorldAction"> 
			<result name="success" type="dispatcher">ex01-success.jsp</result> 
		</action> 
	</package>
</xwork>

不需要关心default-interceptor-ref. 目前我们仅关注活动. 这个配置文件告诉WebWork一个名为helloWebWorld的活动由类lesson03.HelloWebWorldAction实现. 对于这一活动, 我们定义了一个名为success的结果, 它指向页面ex01-success.jsp.
进一步阅读: xwork.xml

一旦我们看到调用活动的代码, 一切会变得清晰:

ex01-index.jsp:

<html>
<head>
<title>WebWork Tutorial - Lesson 3 - Example 1</title>
</head>

<body>

<p>Click the button below to activate HelloWebWorldAction.</p>

<form action="helloWebWorld.action" method="post">
<p><input type="submit" value="Hello!" /></p>
</form>

</body>
</html>

这就是页面与WebWork相结合的方式: 通过访问*.action地址. 回想上一课, 这就是我们为什么注册ServletDispatcher并将它映射到*.action的原因.

当我们点击例子页面上的按钮时, 浏览器将把表单数据发送到地址helloWebWorld.action. 由于这个地址符合映射*.action, Servlet容器将激活WebWork的ServletDispatcher, 它将读出xwork.xml 并查找名为helloWebWorld的活动. 如果找到了, 活动类的一个新的实例将被创建并且方法execute()将被执行.

先来看看活动类:

HelloWebWorldAction.java:

package lesson03; 

import com.opensymphony.xwork.ActionSupport; 

public class HelloWebWorldAction extends ActionSupport { 
	String hello; 
	public String getHello() { 
		return hello; 
	}
	public String execute() throws Exception { 
		hello = "Hello, WebWorld!"; 
		return SUCCESS; 
	} 
}

首先, 该类扩展了com.opensymphony.xwork.ActionSupport并实现了方法public String execute(). 对于新手而言, 所有的活动类都应当这样编写. 其次, execute()方法仅设置了hello属性(property)的值并返回值为"success"的字符串常量SUCCESS.

当ServletDispatcher得到execute()的返回值"success"后, 再次在xwork.xml中查找与success同名的结果, 如配置文件所描述的, 找到并前进到ex01-success.jsp.

让我们看看这个页面做了什么:

ex01-success.jsp:

<%@ taglib uri="webwork" prefix="ww" %> 
<html> 
<head> 
<title>WebWork Tutorial - Lesson 3 - Example 1</title> 
</head> 
<body> 

<ww:property value="hello" /> 

</body> 
</html>

如果运行这个例子, 你会发现页面上显示着"Hello, WebWorld!". 看起来是因为<ww:property value="hello" />标签在刚刚执行的活动类中查找了属性hello. 事实上, 该标签查找页个存取器(accessor)方法, 因此最终调用了getHello(). 由于HelloWebWorldAction被调用并将属性hello设置为"Hello, WebWorld!", 因此getHello()返回该值并被结果页面用于显示.

试一试这个例子!

为活动提供数据

上一个例子演示了WebWork的活动是如何工作的, 但如果不能为活动提供数据我们就不能做更多. 让我们看一个这样的例子:

xwork.xml:

<!DOCTYPE xwork PUBLIC "-//OpenSymphony Group//XWork 1.0//EN"
"http://www.opensymphony.com/xwork/xwork-1.0.dtd">

<xwork>
	<!-- Include webwork defaults (from WebWork JAR). -->
	<include file="webwork-default.xml" />
	
	<!-- Configuration for the default package. -->
	<package name="default" extends="webwork-default">
		<!-- Default interceptor stack. --> 
		<default-interceptor-ref name="defaultStack" /> 
		
		<!-- Action: Lesson 03: HelloAction. -->
		<action name="hello" class="lesson03.HelloAction">
			<result name="error" type="dispatcher">ex02-index.jsp</result>
			<result name="success" type="dispatcher">ex02-success.jsp</result>
		</action>
	</package>
</xwork>

HelloAction.java:

package lesson03;

import com.opensymphony.xwork.ActionSupport;

public class HelloAction extends ActionSupport {
	String person;
	public String getPerson() {
		return person;
	}
	public void setPerson(String person) {
		this.person = person;
	}
	public String execute() throws Exception {
		if ((person == null) || (person.length() == 0)) return ERROR;
		else return SUCCESS;
	}
}

ex02-index.jsp:

<html>
<head>
<title>WebWork Tutorial - Lesson 3 - Example 2</title>
</head>

<body>

<p>What's your name?</p>

<form action="hello.action" method="post">
<p><input type="text" name="person" /><input type="submit" /></p>
</form>

</body>
</html>

ex02-success.jsp:

<%@ taglib uri="webwork" prefix="ww" %>
<html>
<head>
<title>WebWork Tutorial - Lesson 3 - Example 2</title>
</head>
<body>

Hello, <ww:property value="person" />

</body>
</html>

让我们分析一下差别: 本例中我们通过POST方式发送名为person的表单数据. 这样, 在HelloAction新的实例创建之后, WebWork的ServletDispatcher将试图使用发送的数据填充活动的属性person, 因此调用哑(mutator)方法setPerson()(事实上, 这一步工作是由ParametersInterceptor完成的, 我们将在第五课中学到 – 目前, 只需要知道当活动执行时, 属性已经被设置了).

如果你查看活动类的代码, 你会发现在execute()期间, 将检查属性是否已填写(也就是说表单字段是否提供了数据). 如果已填写, 将返回SUCCESS, 从而将请求分发到ex02-success.jsp, 否则, 返回ERROR, 返回ex02-index.jsp.
试一试这个例子!

结果的类型(Types of Result)

通过上面的例子, 当我们提到一个结果是"dispatcher"类型时意味着WebWork查找一个名为dispatcher结果类型并找出它由哪个结果类实现. 只要活动返回该类型的结果, 该结果类的一个实例就被激活.

结果类实现了com.opensymphony.xwork.Result接口. WebWork附带一些已实现的结果类, 但如果需要, 也可以构建自己的结果类. WebWork附带的结果类型已经配置在webwork-default.xml中:

  • dispatcher (com.opensymphony.webwork.dispatcher.ServletDispatcherResult): 将结果转发到指定的地址;
  • redirect (com.opensymphony.webwork.dispatcher.ServletRedirectResult): 将结果重定向到指定的地址. 与dispatcher不同, 重定向不向指定的页面发送表单数据(通过POST或GET);
  • velocity (com.opensymphony.webwork.dispatcher.VelocityResult): 使用一个Velocity模版作为结果. You could use the dispatcher to forward results to Velocity pages if you have如果你在web.xml中配置了 VelocityServlet, 你就可以使用dispatcher将结果转发到Velocity页面, 不过使用Velocity结果是更好的方式. 关于Velocity的更多信息请参阅4.2;
  • chain (com.opensymphony.xwork.ActionChainResult): 将一个活动链接在另一个活动上, 也就是说, 一个活动的结果是另一个活动;
  • xslt (com.opensymphony.webwork.views.xslt.XSLTResult): 用一个由XSLT样式单转换的XML文档作为结果.

进一步阅读: 结果类型(Result Types)

继续进行

上述例子展示了活动和结果的主要概念: 它们是响应请求的代码执行的单元, 完成某些处理然后根据结果将请求转发到其他地址. 虽然这些看起来非常简单, 它却是WebWork功能的核心.

下面列出的另一些可以用活动实现的内容, 仅仅是在继续进行到其他课程前让你了解到WebWork可以做到哪些:

  • 使用截取器, 可以记录每一个活动的执行甚至计算执行时间(第五课);
  • 通过实现ModelDriven接口, 活动可以直接操作业务对象;
  • 对发送到action的数据的校验规则可以在XML文件中配置. 如果某些数据不符合你的规范, 活动不会执行, 同时错误信息会连接到该活动(参见: 校验);
  • 通过将WebWork UI标签与校验框架相关联, 表单能够自动显示由无效输入到值的错误信息(4.1.1);
  • WebWork能够自动为某些活动提供组件, 并允许反转控制(参见: [反转控制与组件]);

下一课将讨论WebWork能够使用的不同类型的试图.


上一课 | 下一课
Document generated by Confluence on Dec 14, 2004 16:36