3.4 其他表示层技术
尽管外观可以用JSP或Struts的标签来实现,但你仍然应该考虑融合其他技术来提高组件的重用,减少维护工作量,减少错误。
3.4.1 特定应用标签
忽略
3.4.2使用包含组合页面
将一个页面放在一个JSP文件中是一个普遍的设计方法,但是许多应用需要将应用中的不同部分显示在一个页面中。例如一个门户应用需要如下功能:
1. 访问门户的搜索引擎
2. 访问门户的讨论区
3. 用户感兴趣的话题
4. 邮件等待指示器
将这些不同的功能交给不同的开发者开发,要完成这个门户应用是比较容易的。然后你就可以使用包含( include)来
将它们组合到一个页面中。有三种不同的包含方式,选择哪种取决于你希望整个输出在什么时候整合:
1. <%@ include file="xxxxx" %>
2. <jsp:include page="xxxxx" flush="true" />
3. bean:include
3.4.3 使用Tiles组合页面
Tiles是一个功能很强的模板库,它可以将很多tile组合成最终的视图。以下是设置向导:
1.创建layout/layout.jsp,它包含标准外观
<html>
<body>
<tiles:insert attribute="body"/>
</body>
</html>
2.创建你的主页/index.jsp
<h1>This is my homepage</h1>
3.创建文件/WEB-INF/tiles-defs.xml
<tiles-definitions>
<definition
name="layout"
path="/layout/layout.jsp">
<put name="body" value=""/>
</definition>
<definition name="homepage" extends="layout">
<put
name="body"
value="/index.jsp"/>
</definition>
<tiles-definitions>
4.在文件struts-config.xml中设置TilesPlugin
<plug-in
className="org.apache.struts.tiles.TilesPlugin">
<set-property
property="definitions-config"
value="/WEB-INF/tiles-defs.xml"/>
</plug-in>
5.在struts-config.xml文件中设置一个Action指向你的主页
<action path="/index" type="org.apache.struts.actions.ForwardAction" parameter="homepage"/>
3.4.4 图片渲染组件
一些应用需要动态产生图片,有两种方法符合如下需求:
1. 产生一个执行Servlet请求的超链接 Servlet将使用图形库来产生图片
2. 将JAVA Applet嵌入在HTML页面中来产生图片
3.4.5 文本输出
一些应用需要动态的产生文本(如XML),因为整个页面将通过PrinterWriter输出,我们可以通过设置PrinterWriter的属性来做到:
response.setContentType("text/plain"); // or text/xml
PrintWriter writer = response.getWriter();
// use writer to render text
return(null);
3.4.6 Struts EL 标签库
Struts基本的标签都是依赖rtexprvalue(runtime scriptlet expression)来动态计算属性
的值,例如,要根据资源关键值打印来自属性文件中的信息
<bean:message key='<%= stringvar %>'/> 这样写是假定stringvar是JSP中的
脚本变量,如果使用Struts的EL标签库就会是如下形式:
<bean-el:message key="${stringvar}"/>
4 创建控制(Controller)组件 4.1 概述
我们已经知道如何去构建Model和View组件,现在我们将集中到Controller组件。Struts包含了一个映射请求URI到Action类的Servlet。因此你编写WEB应用时在Controller组件这方面要做的工作如下:
1.编写AtionForm作为Model和View的中介
2.编写Action(继承org.apache.struts.action.Action)来处理请求
3.为每一个逻辑请求在struts-config.xml.中编写一个ActionMapping
4.2 ActionServlet
对于熟悉MVC架构的人来讲,ActionServlet就代表着 C ? Controller。Controller的任务是:
1.处理用户请求
2.根据用户请求来决定用户将要完成什么任务
3.将Model的数据传到视图(View)
4.选择合适的视图响应请求
Controller会将大部分工作放到Request Processor和Action 类中。
4.2.1 请求处理器(Request Processor)
RequestProcessor对每个请求做核心处理的地方,它要做的处理如下:
1.processPath - 确定请求的路径,以备后面的处理检索ActionMapping
2.processLocale ? 为请求选择一个locale
3.processContent - 设置默认的内容(Content)类型.
4.processNoCache ? 设置响应头:Pragma,Cache-Control,Expires
5.processPreprocess - RequestProcessor让子类重载实现,默认返回真(True),如果子类重载此方法并返回真,则该请求将继续处理流程,如果返回假,则意味着你处理了该请求,处理流程直接返回。
6.processMapping - 确定请求所对应路径的ActionMapping
7.processRoles - 保证请求的用户具备特定的角色
8.processActionForm - 实例化ActioForm并且把它放在适当的作用域中。
9.processPopulate - 用请求中的数据组装ActionForm
10.processValidate - 校验ActionForm中的数据
11.processForward - 如果映射是一个转向( Forward)指令,就转向到特定的路径。
12.processInclude - 如果映射是一个包含(Include)指令,就将映射指定的路径的输出结果包含进来。
13.processActionCreate - 实例化映射指定的Action.
14.processActionPerform ? 执行Action的perform或excute方法。
15.processForwardConfig - 最后RequetProcessor使用Action类返回的ActionForward来选择下一个资源。大多数的AtionForward将会导航到显示页面输出响应。
4.3 ActionForm类
一个ActionForm代表着一个与用户交互的HTML表单。ActionForm中的属性来存储表单中的状态,并且有getter,setter方法来访问他们。ActionForm可以存储在session或request的作用域中(默认的是session).如果ActionForm放在session中记得要实现reset方法,以备每次使用ActionForm时都会初始化。Struts根据请求中的参数设置ActionForm的属性并且把经过校验后的ActionForm传到Action的execute方法。
当你在编写ActionForm时必须坚持如下原则:
1.ActionForm本身没有任何特定的方法被实现。仅仅用来表示它是整个框架中一个特定的角色。ActinForm中只有getter,setter方法,并没有任何商业逻辑。
2.AtionForm提供标准的校验机制。如果你重载了ActionForm的validate方法,并且在资源属性文件中提供了错误消息,那么Struts就会自动校验表单中的数据。当然你也可以忽略ActionForm中的校验,在Action类中来实现校验。
3.为输入表单中的每一个输入定义属性。输入域的名称和ActionForm中属性的名称必须符合JAVA规范。例如一个输入域的名称username将会导致ActionForm中的setUsername被调用。
4.也可以为Form中的按钮或其他控件定义属性。当提交表单时这将有利于你知道哪个控件被选中了。
5.把ActionForm当作HTTP和Action之间的防火墙。ActionForm的方法可以校验所有必须的属性已经存在了并且包含合理的值。如果校验失败请求将不会被Action类处理。
6.你可能会放一个Bean的实例在ActinForm中,这样你就会用到嵌套属性引用。例如,你可能有一个“customer”在ActionForm中,然后在页面中用“customer.name”来引用属性。
4.3.1 DynaActionForm
维护一个具体的ActionForm是要耗费时间的。特别是ActionForm越来越多并且都是校验一些简单的属性时你可能会感觉到一股挫折感。
这个瓶颈通过DynaActionForm会有所减轻。通过在Struts的配置文件中列出属性,类型和默认值来替代以前的定义一个新类,并且添加getter/setter方法。例如,在struts-config.xml中添加一个UserForm:
<form-bean
name="UserForm"
type="org.apache.struts.action.DynaActionForm">
<form-property
name="givenName"
type="java.lang.String"
initial="John"/>
<form-property
name="familyName"
type="java.lang.String"
initial="Smith"/>
</form-bean>
DynaActionForm支持的数据类型:
java.lang.BigDecimal
java.lang.BigInteger
boolean and java.lang.Boolean
byte and java.lang.Byte
char and java.lang.Character
java.lang.Class
double and java.lang.Double
float and java.lang.Float
int and java.lang.Integer
long and java.lang.Long
short and java.lang.Short