资源描述
第五章 Struts标签
5.1标签——就是你
Struts中包含功能强大的预先定义好的JSP标签库,这些标签库通过JSP页面和框架结构集成在一起。同时新的标准标签库——JavaServer Tag Library [Sun,JSTL]也即将制定完成。
在本章中,我们会介绍如何在应用程序中使用扩展标签库。我们会使用标签来预先填充文本域或者选择列表,以及控制检查框。Struts和JavaScript也可以很好地一起工作,因此你也可以使用JavaScript来完成一些HTML不可能完成的工作。
5.1.1 JSP标签库——有什么优点.
在本书中我们一直都使用JSP,但我们很少说到什么是JSP以及我们为什么使用它们。因此让我们现在回过头快速地回顾一下为什么使用JSP标签来构造Web页面。
大多数基于Web的应用程序都依赖于使用标准的浏览器来显示信息。相应的,标准的浏览器也依赖标准的HTML语言作为格式化语言。通常应用程序显示的信息不是静态的、预先定义好的页面,而是针对一个特定用户的动态内容。最开始的时候,这听起来并不是一件困难的工作。毕竟Java的servlet允许你可以自由地输出HTML语句——我们可以如同向显示器和打印机输出我们的文本文件一样输出HTML语句:只使用pnntln(“任何内容”)。显示了我们如何使用标准的servlet来构造一个页面。
app.ChaseBean chase = new ChaseBean("dog","cat");
// ...
out.println("<HTML>");
out.println("<HEAD><TITLE>The Chase<TITLE><HEAD>");
out.println("<BODY>");
out.println("<H1>Welcome to the Chase</H1>");
out.println("<H2>Our story so far:</H2>");
out.println("<FONT SIZE=\"+1\" FACE=\"Times\" COLOR=\"#FFFFFF">);
out.print("The big ");
out.print(chase.getChaser());
out.print(" & ");
out.print("the little )"
out.print(chase.getChasee());
out.println(" chased each other. ");
out.println("</FONT>");
out.println("</BODY>");
out.println("</HTML>");
图5-1 使用老方法生成HTML内容
当创建HTML代码的时候,两个动态变量:dog和cat也被集成到页面中了。游览器:处理静态的、预先编写好的页面一样接收和显示该页面。如果ChaseBean被设置成其他(量,例如fox和hound,则用户就会看到一个完全不同的页面。图10-2显示了浏览器会接收到的内容以及显示结果。
图5-2 浏览器收到的内容及显示结果
但是如果复杂的页面也用这种方法进行输出,则既难以让人接受也增加了维护的负担。一个改进的方法是使用特定的Java类以及其方法而不是println方法来生成HTML代码。图图5-3显示了如何用嵌套的Java类来生成HTML语言。
至少图5-3使用的方法使得我们不需要直接和HTML标签打交道。但是就算是最好的HTML生成器也使得我们很难了解最终页面的全貌。没有几个程序员能够从这些代码中想象出页面到底是什么样子。要看到最新的结果,程序员不得不重新编译这些类并且可能需要再次部署它们。
app.ChaseBean chase = new ChaseBean("dog","cat");
// ...
Html html = new Html()
.addElement(new Head()
.addElement(new Title("The Chase")))
.addElement(new Body()
.addElement(new H1("Welcome to the Chase"))
.addElement(new H2("Our story so far:"))
.addElement(new Font().setSize("+1")
.setColor(HtmlColor.WHITE)
.setFace("Times")
.addElement(chase.getChaser());
.addElement(" & ");
.addElement("the little )"
.addElement(chase.getChasee());
.addElement(" chased each other. ");
output(out);
图5-3 使用嵌套的类来生成HTML,比使用Println好一些
1. 服务器页面
对该问题的一个常用解决方法就是使用服务器页面来显示动态内容。有多种服务器页面:ASP,ColdFusion页面,PHP页面,Velocity模板,当然还要有JSP。但是他们都有一些基本特点:
·创造一个类似于HTML的页面,其中包含服务器端页面的标签来标示那些动态的内容。
·当接收到一个该页面的请求时,使用服务器端页面的来构造动态响应。
·响应作为标准的HTML被返回。
这些方法的主要优点在于:
·服务器页面不是需要被编译进人核心应用程序的程序文件。
·服务器的页面构成一个标准的Web页面。
特别是对于那些非程序员而言,他们可以很容易地创建和维护服务器端页面。甚至可以使用一些图形化的编辑器(例如Macromedia公司的Dreamweaver)来维护这些服务器页面。
2. JSP
JSP使用两种截然不同的方法来创建服务器的页面标签。程序员可以直接在页面上的seriptlets中放置Java代码。这些代码快速、相对简单并且功能强大。图5-4显示了该方法:
第二种方法是使用扩展标签。JSP标签类似于HTML标签,使用相似的格式和语法。JSP标签需要更多的精力进行编写,但是一旦编写完成,很长一段时间内JSP标签的使用和维护更加简单。图5-5显示了使用标签库的方法:
<jsp:UseBean id="chase" scope="page" class="app.ChaseBean"/>
<HTML>
<HEAD><TITLE>The Chase</TITLE></HEAD>
<BODY>
<H1>Welcome to the Chase</H1>
<H2>Our story so far:</H2>
<FONT SIZE="+1" FACE="Times" COLOR="#FFFFFF">
The big "<%= chase.getChaser() %>" &
the little "<%= chase.getChasee()%>">
chased each other.
</FONT>
</BODY>
</HTML>
图5-4 scriptlets允许混合使用Java代码、表达式和HTML语句
<%@ taglib uri="/tags/struts-bean" prefix="bean" %
<HTML>
<HEAD><TITLE>The Chase</TITLE></HEAD>
<BODY>
<H1>Welcome to the Chase</H1>
<H2>Our story so far:</H2>
<FONT SIZE="+1" FACE="Times" COLOR="#FFFFFF">
The big <bean:write name="chase" property="chaser"/>
& the little
<bean:write name="chase" property="chasee"/>
chased each other.
</FONT>
</BODY>
</HTML>
图5-5使用JSP标签库的方法
5.1.2 Struts和JSTL
尽管Struts标签具有强大的功能并且容易使用,但是他们并不是唯一可以被使用的标签库。Sun的JSTL提供了很多很有用的标签集合,其中一些的功能和Struts标签库是重复的。JSTL要求容器支持Servlets2.3和JSP1.2,例如Tomcat4或Resin2。很短的时间内,我们希望大多数容器都可以针对JSTL进行优化,使得大多数应用程序都可以将它作为基本标签库进行使用。
当然,JSTL并不排斥使用用户定制的扩展标签。在很多情况下,程序员都会觉得编写一个标签使用特定的方法来完成特定的工作是很方便的。但是和传统的Struts标签库一样,JSTL帮助程序员编写大多数应用程序都会使用的常见操作。
是不是我们应该在可能的情况全部使用JSTL标签而不是Struts标签呢?答案是肯定的。如果你所使用的容器支持Servlet2.3 和JSP1.2,则应该尽量使用JSTL标签。大多数Struts标签都是为了实现某个功能而编写的,而不是Struts框架结构必不可少的一部分。如果JSTL 在开发框架结构时已经存在,则并不需要编写大多数Struts标签。
当然,Struts标签还是很多应用程序中的一部分,并且在一段时间内依旧是Struts发行包的一部份。可以保证的实Struts开发小组不会试图与JSTL竞争。新Struts标签或者是基于JSTL或者会使附属于JSTL。
注意 在本书将被印刷。时,一个JSTL版本的Struts标签库已经被加入到开发版本中。该标签库应该是Struts1.1最终发行版本的一部分。本书的网站会根据Strutsl.1的更新来进行修正或者添加附录。
JSTL表达式语言JSTL包括了一个新的表达式语言(EL),该语言可以替代脚本语言。对于很多使用自己开发的标签库的用户而言,因为他们常常希望将多个动态参数传递给自己的JSP标签,因此该语言显得尤其有用。
现在,在客户自己开发的标签中有一个空白位。另外一个标签的输出结果应该作为属性传递给该标签中并作为该空白位的值。该标签的其他属性值都应该在该标签内部。但是在一个标签中包含另外一个标签的表达式是不允许的:
因此,
<some:tag attribute="<bean:message key='...'/>">
是不可能通过编译的。其实我们可以使用如下的JSP语句
<some:tag><bean:message key="..." /></some:tag>
尽管这样做可以,但是有时候多个属性值需要设定,而上面的方法就无能为力。对于Struts标签,我们可以通过将对应的bean指定名字而不是数据来绕过该限制,然后标签可以通过该bean来获得对应的属性值。但是对于其他标签,我们就不得不使用运行时刻表达式了,例如:
<some:tag attribute='<%=myDynamicString + "txt" %>'/>
当使用带有JSP标签属性的运行时刻表达式时,关键一点是要记住对属性值我们需要使用完整的表达式,正如我们上面的例子说明的那样。否则不能通过编译。
而JSTL表达式语言还提供了另一种解决方法:
<c:set var="msg"><bean:message key="..." /></c:set>
<tag attribute="$msg"/>
此次,我们首先将<bean:message>标签的输出结果作为一个页面范围属性,然后使用JSTL的表达式语言将该属性写入另外一个(非JSTL)标签的属性中去。
当然,JSTL的能力远远超过我们上面小例子所表现的。一般而言,我们应该使用JSTL的标签库,而不是Struts的bean或者logci标签库。但是,从开始,你可能不得不继续实现Struts的html标签库,因为这些标签并不是特定的。
因为JSTL和Struts框架结构共享一些一致的目标,因此它们可以子在一起很好地工作。它们都是为了降低在JSP中使用脚本语言的比例,同时也都是鼓励在MVC体系结构中使用ISP作为视图层。
5.1.3 Struts标签库和MVC
Struts的JSP标签可以提供大多数应用程序所需要俄功能来创建MVC结构的表现层。(关于MVC结构的说明,请参考第2章)。因为很多程序员都希望自己的基于Web的应用程序能够和那些以页面为中心的老式的基于Modell的应用程序有清楚的区别,因此这些特性就显得更加重要了。对于一个正确设计的基于Model 2(MVC)架构的应用程序而言,一个请求是不会直接到达表现层页面的。请求都是先由控制器进行处理。正如图10-6所示,仅仅在那些业务数据被获取并且业务逻辑已经进行了处理后,控制器才会将控制转向表现层页面。
此时所有的其他事情都已经处理完了,因此表现层的责任仅仅就是输出结果——这就是JSP标签要处理的事情。JSP标签可以访问存放在servlet上下文中的数据对象,并且使用这些对象中的数据来创建动态的内容。
也许你现在已经猜出来了,5.1节的标题头有着双重意思。对于一个MVC环境而言,从本质上说,将控制器转给页面就是控制器对页面说“标签——数据给你了”。同时,相对于老的方法而言,标签就是数据。
更进一步,在5.2小节我们将简单地介绍如何和标签库一起工作的基本知识:包括如何创建和安装标签库,以及标签库不能做什么。在5.3小节,我们将介绍Struts标签库,我们将主要关注整个类库的设计。在5.4小节,我们将介绍如何使用Struts标签库,特别包括了使用标签库的细节,例如基础知识,主要技术和常见应用程序。
本章的主要目的是降低读者学习Struts标签库的学习曲线,使得读者可以更快地将Struts标签库应用到自己的应用程序中去。Struts标签库开发人员手册和技术文档(StrutsTaglib DveloperGuides and technicaldocumentation)是非常好的资料,我们也建议读者认真阅读它们。但是为了更好地帮助读者开始使用Struts标签库,本章提供了对于扩展标签库以及Struts标签库的更加通用的解释,同时还着重说明了它们是如何工作的,以及如何在自己的应用程序中使用这些标签库。
客户
控制器
JSP
数据库
图5-6 一个基于Model2-MVC的应用程序的程序流
5.2使用扩展标签库
在5.1节中,我们简单介绍了基于Java的Web应用程序是如何从使用命令行方法来产生输出到使用模板以及使用外部可视化编辑工具来编辑服务器端页面来产生输出的过程。在本节中,我们将介绍扩展标签库是如何编写的以及扩展标签库的能力范围。同时,我们还要介绍Struts标签库。这些内容将会是本章后面内容(如何使用Struts标签库)的基础。
5.2.1 扩展标签是如何工作的
JSP的标签库是使用扩展标签库APl用Java编写的。该类会分析XML格式中的标签,并且使用该标签的值作为参数来调用该类的方法。实际上,扩展标签使得你可以使用类似于标准的HTML格式的XML语法来调用Java方法。例如,标准的HTMLbase标签的使用方法如下:
<base href="
而Strutsbase标签则是<html:base/>。
在JSP页面中,Struts标签<html:base>会被转换成为标准的HTML格式标签,同时恰当的路径(或URL)也会自动地填充进去。
在这个过程中,存在一个名为BaseTag的类来对应base这个标签。BaseTag类继承TagSupport类(见代码清单5-1),同时也重载了一个热点方法doStartTag。这是一个通用的Java方法,它可以用来构造对应的HTML标签。该方法和你使用servlet来直接输出对应的HTTP响应是一样的。
代码清单5-1 一个BaseTag例子
public class BaseTag extends TagSupport {
// ...
public int doStartTag() throws JspException {
HttpServletRequest request =(HttpServletRequest)PageContext.getRequest();
StringBuffer buf = new StringBuffer("<base href=\"");
buf.append(request.getScheme());
buf.append("://");
buf.append(request.getServerName());
buf.append(request.getRequestURI());
buf.append("\"");
if (target != null) {
buf.append(" target=\"");
buf.append(target);
buf.append("\"");
}
buf.append(">");
JspWriter out = PageContext.getOut();
try {
out.write(buf.toString());
}
catch (IOException e) {
PageContext.setAttribute(Action.EXCEPTION_KEY, e,
PageContext.REQUEST_SCOPE);
throw new JspException(messages.getMessage(
"common.io", e.toString()));
}
return EVAL_BODY_INCLUDE;
}
}
该例子可能会使得你觉得和图5-1和图5-3所示的很相似。但是该方法的主要区别在于这是一个特别定制的类,包含了对应的标签,也可以被重用。应用程序可以共享标签库,而标签可以很容易地和JSP/HTML标签进行集成。
实际上,大多数程序员并不需要编写自己的标签。市场上已经存在很多通用的标签库,其中就包括JSTL。一般情况下,程序员都是简单地将一个已经存在的标签库导人到某个页面(页面可以被重用吗?)中,然后就可以使用标签库中的标签了,对于程序员而言,这些标签的功能就如同对于标准的HTML标签扩展一样。
在讨论标签时,程序员使用一系列的相关术语。一个快速地术语表可以帮助你更快地了解这些术语。表5—1定义了在讨论标签库时常用的一些词汇。
表5-1 JSP标准库词汇.
名称.
定义.
Tag extension(扩展标签).
标签库使用的机制(或者API),来使用JSP可以使用标签库。
Tag library(标签库).
一系列动作(标签),它们封装了在JSP中使用的一些动作。
Taglib(标签库).
标签库的常见简写,一般发音为tag-libe
Custom tag JSP tag(客户化的标签或者JSP标签).
组成标签库的一个动作(标签)。
5.3 Struts 标签库
首先要声明的是,应用程序不是一定要使用Struts标签库。标签库是Java的标准技术。除了Struts的标签库以外,还有其他的标签库可以使用。其中就包括Sun的JSTL标签库、Javarta的标签库、以及Improve提供的Struts-Layout标签库等等很多各种各样的标签库。所有这些标签库都可以和Struts标签库一起工作。如果你觉得这些标签库提供的预先定义的扩展功能并不能满足自己的需要,或者想使得标签的工作更加简单化,你可以编写自己的标签库。自己编写的标签可以和其他的标签一起混和使用而不会有其他问题。
Struts的发行版本中包含四个关键的标签库:bean,html,logic和nested.如表10-2所示。在html标签库中的标签都是依赖于Struts框架结构。而其他三个标签库中的标签并不依赖于Struts框架结构,因此可以脱离Struts框架结构而在其他应用程序中使用。
在本节,我们会了解Struts标签库中的常用特性,然后对每一个标签库进行介绍。本节所包含的内容并不能替代Struts开发人员手册以及技术说明手册中的内容。对于每一个标签的特定细节,我们还是建议你参考技术说明手册中的内容。本章是为10.4小节服务的,在那节中,我们会学习到如何使用Struts标签。
表5-2 四个关键的Struts标签
标签库
描述
bean
用来访问JavaBean以及它们属性的标签,同时也用来创建新的JavaBean
html
用来创建HTML输入表单以及核Struts框架结构打交道的相关标签
logic
用来对于输出结果进行分析、对于对象集合进行遍历来生成输出页面的标签,同时也负责应用程序的流程管理
nested
对于Struts标签提供增强嵌套功能的标签
5.3.1 Struts标签库的常用功能
Strtus标签库提供了一些常用方法来更加方便地使用标签。这些方法包括自动上下文管理,通用属性名,扩展语法以及一些通用的错误属性。
1.自动上下文管理
Java的servlet可以将对象存放在不同的共享对象中,这些共享对象被称为上下文。上下文可以看成是一个公共的留言簿。一个应用程序中的任何servlet都既可以将任何东西放到该上下文中,也可以从上下文中来读取任何放置在其中的对象。
在搜寻一个对象的时候,Struts标签会自动地对全部标准上下文进行搜索——页面、HTTP请求、会话以及应用程序,同时使用第一个找到的对象。同时,也可以通过指定特定的上下文来保证Struts标签仅仅会在特定的上下文中找到合适的对象。
2.通用属性名
Strots标签的一个很重要的特性就是它们的设计目标就是将JavaBean内的值传递到页面上。标签的通用属性名(例如id,name,propedy和soope),是设通过控制器进行设置的,然后某些辅助bean类会使用这些属性。表10-3列出了这四个最常见的属性。
表5-3 Struts标签库使用一致的属性名集合
属性
描述
id
通过一个客户化的标签用来定义要创建的任何页面脚本变量的名字
name
定义用来寻找一个存在bean的键值。如果scope已经设定了值,则仅仅在指定的上下文中寻找。否则,会按照标准的顺序进行搜寻(页面,HTTP请求,会话和应用程序)
property
定义要获取值的属性名。如果没有指定,则使用该对象本身
scope
定义在什么上下文(页面,HTTP请求,会话和应用程序)中进行搜寻。如果没有指定,则使用标准的顺序进行搜寻。页面变量(见id属性)会在同样的上下文中进行创建。
下面是一个使用了所有四个属性的例子:
<logic:iteratescope="request"name="result"
property="collection"id="row"><%-- markup --%>
</logic:iterate>
该例子是在标准的HTTP请求上下文中来寻找一个名为result的bean。然后,获取名为conllection的属性值。对结果进行遍历,将每个结果,都作为一个页面变量row进行输出。该操作直到结果集遍历结束,碰到<logic:iterate>标签为止。
其他的Struts标签也是通过类似的方法来使用这些标签,这样做可以减低Struts标签的学习曲线。
3.扩展语法
Struts标签库不仅仅支持JSP中使用的标签的简单引用,还支持嵌套引用。通过嵌套引用,你可以对于一个Struts标签进行这样的调用:
property= "foo.Bar.baz"
这告诉Struts进行如下的调用:
getFoo().getBar().setBaz();
或者是
getFoo().getBar().setBaz(value);
从Struts1.1开始,还可以在其中使用索引
property= "foo[2] "
它等价于getFoo(2);或者是setFoo(2,value);
要注意的是,该索引是从零开始计算的,和Java表达式的表示方法一样。
4.运行时刻表达式
尽管Struts标签库的设计目的是为了避免在JSP中使用页面脚本,但是如果没有其他的方法,Struts标签的全部属性都是可以通过运行时刻表达式(页面脚本)来获取。当使用页面脚本来生成属性,要注意的一点是需要保证表达式的完整性。
例如,下面的一点是不完整的:
<html:link href='<%= "/" + name %>/index.jsp>'>
而这个才是正确的:
<html:link href='<%= "/" + name +"/index.jsp" %>'>
正如上面代码片断所示,表达式中一定要包括通过引号包裹起来的全部属性。关于如何混和使用JSP标签以及页面描述语言,请参看Struts的标签库开发人员手册。要记住的一点是,Struts开发小组以及很多其他的程序员,都只是在万不得已的时候才使用页面脚本。
5.通用的错误处理
JSP规范允许程序员定义一个默认的错误页面。当处理某个页面的时候发生了错误,容器会自动将控制权转移给预先定义好的该错误页面,而不是显示一个空白页面。如果某个Struts标签抛出一个异常,则在HTTP请求的属性中使用org.apache.struts.action.EXCEPTION来定义要显示的错误页面。
这使得JSP错误显示页面可以有机会来处理真正引起错误的异常。
5.3.2 bean标签
在标签和JavaBean间有着很强的联系。对于标签而言,最开始的一个设计目标就是为了提供JSP和JavaBean间的一个接口。在实现该目标后,Struts提供了一个很小但是特别有用的标签库来实现对于JavaBean以及其他相关对象的操作。在表1-4中列出了该标签库中的11个标签,可以使用这些标签来实现如下的目的:
● 利用HTTP请求头、HTTP请求的参数、cookie或者任何上下文中已经存在的对象来创建一个JSP的页面变量。
● 从另外一个HTTP请求(include模式)的响应中、或者从应用程序资源中或者从Struts的配置文件中创建新的JavaBean。
● 测定出一个集合或者映射中对象的个数。
● 针对当前用户,从应用程序资源中自动创建本地化的消息。
● 对于任何当前可用的JavaBean,设定给定属性的值。
在这些标签中,仅仅message和struts标签是和Struts框架结构紧密相关的。其他的9个标签可以在其他应用程序中自由使用。
表5-4 Struts的bean标签
标签名
描述
cookie
基于指定的cookie中的值,来定义一个脚本变量
define
基于指定的JavaBean中的值,来定义一个脚本变量
header
基于指定的HTTP请求中的值,来定义一个脚本变量
include
获取应用程序动态生成的响应,并且将它作为一个bean来使得其他部分可以使用
message
生成一个国际化的消息串
page
将页面上下文中的一个指定元素转换为bean使用
parameter
基于HTTP请求中指定参数的值,来定义一个脚本变量
resource
装载应用程序资源,并且作为bean使用
size
定义一个集合或者映射中元素的个数
struts
将Struts内部的配置对象作为bean来使用
write
输出一个指定bean属性的值
通过联合使用这些功能,JSP的设计者就可以通过这些标签来实现那些只有页面脚本语言才能使用的大量功能。这包括在CGI程序中经常使用的小技巧,例如改写HTTP请求头:
<bean:header id="browser" name="user-Agent"/>
<P>You are viewing this page with: <bean:write name="browser"/></P>
以及一些其他的功能,例如从cookie中创建一个新对象:
<bean:cookieid="username"name="UserName"scope="session"
value="New User" />
<P>Welcome <bean:write name="username" property="value"/!</P>
在上面的例子中,如果cookie中已经存放了用户名,则该名字就会显示,而不是显示“new User”。
1.使用bean标签的最佳实践
当程序员将应用程序从基于JSP的Model1移植到Model2的时候,Struts的bean标签提供了很多高级功能来协助该过程。很多bean标签中库中的标签,例如<bean:cookie>和<bean:header>提供的功能都可以通过Struts的Action来实现。很多Struts的程序员都倾向于将JSP页面变成模版模式。那些和业务逻辑相关的动作,例如处理cookie,都和可以通过Struts的Action进行处理,然后传递给页面。
通常而言,最常见的bean标签应该是<bean:write>和<bean:message>
2.write和message标签
<bean:write>是我们下一节要讨论的html标签的只读版本。作为一个灵活而又高效率的标签,它使用反射来获取某个给定属性的属性值。
<bean:writename="shoppingCart"property="itemSum"/>
如果获取的属性值不是一个Java的基本对象,则该对象的toString()方法会被调用。
<bean:message>标签可以帮助应用程序实现国际化。Java定义了一个标准对象来存储一个用户的区域和语言。该对象被称为locale(java.util.locale)。在默认情况下,Struts框架结构会为每一个用户创建一个locale对象,并且使用一个众所周知的键值将它存放在用户的session上下文中。程序员要做的仅仅是提供一个消息对应的键值。而Struts的相关模块,例如<bean:message>标签,则会自动寻找和该键值相关的消息。而Struts框架结构会自动从应用程序资源文件中提取和该用户locale对象相关的对应消息。
假设一个标签如下:
<bean:message key = "inquiry">
则对于一个French/Canada的用户而言,输出结果是:
"Comment allez-vous?"
但是对于一个English/United Struts用户而言,输出的结果是:
"How are you ?"
5.3.3 html标签
HTML规范提供了数量有限但是很有用的控件。一般浏览器都支持这些控件。这些控件包括按钮、检查框、圆按钮、选单、文本显示框以及隐藏控件。设计这些控件的目的就是为了使得应用程序可以预先偏用动态内容来填充它们。而如何获取数据以及如何填充这些数据的工作就留给了应用程序。
使用脚本语言(包括JSP的脚本语言)来提供动态内容的应用程序一般都是通过混和使用HTML和脚本语言来填充HTML控件的。例如,要使用标准的JavaBean和JSP脚本语言来填充一个HTML的文本框,大多数的程序员会编写如下的代码:
<input type="text"
name="firstName"
value="<%= formBean.getFirstName() %>"/>
注意 附带说一下,我们并不阻止程序员使用脚本语言来输出HTML控件。Struts标签并没有什么特别的倾向。当一个表单被提交给Struts控制器的时候,Struts控制器所看见的仅仅是一个标准HTTP请求。无论该HTTP请求是如何生成的,Struts控制器都会负责任地从事如下的动作:填充相关联的ActionForm bean,调用ActionFormbean的validate方法,然后将ActionForm对象传递给Action的perform方法或者将请求返回要求更多的输入。如何通过HTTP请求来生成HTML表单并不重要,对于使用Struts的开发人员而言,重要的是JSP程序员可以通过一套完整的标签来编写HTML控件,而不用借助于页面脚本语言了。
下面就是如何使用Struts的html控件来使用同样的功能:
<html:text property="firstName"/>
下面是这两种方法间的区别:
●尽管没有在代码中包含,但是使用页面脚本的例子需要在页面的某个地方预先定义formBean为一个页面变量。而Struts标签不需要任何其他工作就可以找到该bean。
●默认情况下,Struts标签会在表单的其他地方使用同一个bearl,因此并不需要对于每一个控件都进行指定。
1.对应的HTML元素
Struts的HTMl标签库提供了超过20个的标签来辅助程序员填充HTML控件以及对应的属性。如表5-5所示,大多数标签都是对应的标准HTML元素。
表5-5 Struts的HTML标签库如何映射到HTML元素上
Struts的HTML标签
对应的HTML元素
base
<base>
button
<input type="button">
cheekbox,multibox
<input type="checkbox">
errors
没有对应的元素,显示一系列积累的错误信息
file
<input type="file">
form
<form>
hidden
<input type="hidden">
html
<html>
image
<input type="image">
img
<img>
link
<a>
messages
没有对应的元素。显示一系列积累的错误消息(Struts1.1)
option,options
<option>
password
<input type="password">
radio
<input type="radio">
reset
<input type="reset">
rewrite
没有对应的元素,输出一个URL编码的路径
select
<select>
submit
<input type="submit">
text
<input type="text">
textarea
<textarea>
这种一对一的对应关系使得将现存的JSP或者HTMl页面转换成为使用Struts标签的页面的过程是一个很简单的过程。例如,无论在什么地方,如果一个如下的HTML元素:
<input type="text"name="username">
则可以用如下的使用html标签的语句进行替换
<html:text property="username"/>
现在已经有工具可以使用已存在的HTML文件自动输出对应的Struts版本文件[Objectwave],[Ramaiah]。使用这样的工具可以使得软件开发有一个很好的开始。
2.通用属性
和Sreuts的其它标签一样,Struts的HTML标签也共享一些通用属性,如表5-6所示。
表5-6 Struts 的HTML标签使用的与属性名一致的集合
属性
目的
name
用来对控件提供数据的ActionForm或者其他JavaBean的
展开阅读全文