Struts 培训教程
1 概述
在这份教程中,将介绍struts框架和与struts框架有关的技术。该教程主要分为以下几部分:
§ MVC模式
§ Struts的概念和体系结构
§ Struts中主要技术的介绍
§ 用jBuilder8开发struts应用程序
2 MVC模式
所谓的MVC模式,即 模型—视图—控制器(model—view--controller)模式。其结构图如下:
§ Model端
在MVC中,模型是执行某些任务的代码,而这部分代码并没有任何逻辑决定它对用户端的表示方法。Model只有纯粹的功能性接口,也就是一系列的公开方法,通过这些公开方法,便可以取得模型端的所有功能。在struts框架中,Model端是用Action和EJB技术实现的。
§ View端
在MVC模式里,一个Model可以有几个View端,而实际上复数的View端是使用MVC的原始动机。使用MVC模式可以允许多于一个的View端存在,并可以在需要的时候动态的登记上所需要的View.
§ Controller端
MVC模式的视图端是与MVC的控制器结合使用的。当用户端与相应的视图发生交互时,用户可以通过视窗更新模型的状态,而这种更新是通过控制器端进行的。控制器端通过调用模型端的方法更改其状态值。与此同时,控制器端会通知所有的登记了的视图刷新显示给用户的表示。
在现在的j2ee应用中,我们在开发web server时基本上都是采用MVC模式来开发的,j2ee规范也相应的为我们提供了技术支持,请看下图:
1 2
3
5 4
7
1 浏览器用户执行servlet的doGet方法;
2 servlet根据不同的请求,将他们分发到不同的Action中。在这里,servlet的作用就好比是controller;
3 Action调用EJB层的商务逻辑程序处理用户的请求;
4 EJB层返回给Action处理结果;
5 Action 对将处理结果返回给servlet。在这里,可以将Action 和 EJB共同看成是model
6 servlet将信息发送给JSP页面。这里的JSP就相当于view;
7 browser用户浏览JSP页面;
大家可以看到,JSP、servlet和EJB各自在MVC模式中所起到的作用。
使用MVC的优点如下:
§ 可靠性(Reliability):将表示层和处理层完全分开,可以在不重新编译model和controller的情况下修改view层。
§ 复用性和适应性(reuse & adaptability):MVC使你可以使用多种view去访问相同的model。
§ 快速开发(Rapid deployment):因为MVC清晰的将表示层和处理层分开,所以使得不同的程序员可以各司其则,增加开发速度。
§ 可维护性(Maintainability):清晰的分层同样使得代码清晰、程序的可维护性提高。
3 Struts的概念和体系结构
§ 概述
struts源自于apache的jakarta工程,是一个开源代码工程(http://jakarta.apache.org/)。现在struts最新的版本是1.2,而jBuilder自带的版本是1.02。struts是一个完全遵照MVC模型设计的,web层的框架。
§ struts与MVC模式
struts是一个完全遵照MVC模型设计的,web层的框架。在struts中,使用到了jsp、javabean、taglib和servlet技术。下图是一个描述了struts框架的应用请求的执行路径:
这个过程大体可以被分成5个基本步骤:
1 view发起一个请求
2 ActionServlet(servlet技术实现)接受这个请求,它根据一份xml文件来得到处理这个请求的Action对象,并将请求发送给这个Action对象。
3 Action对象接受这个请求,并调用model(EJB)去处理这个请求,并将处理结果返回给ActionServlet。
4 ActionServlet根据Action 的返回结果中的信息,决定将处理结果返回给对应的view。
5 view得到处理结果,并将他显示给用户。
3.1 THE MODEL
Struts框架提供Action作为model的一种实现。Action 是继承org.apache.struts.action. Action的类,他用来处理用户的请求,并将处理结果封装在HttpServletRequest中,返回给ActionServlet。
3.2 THE VIEW
Struts用JSP、taglib和javabean技术去实现view。JSP用来显示视图;struts通过使用自己定义的一组taglib来控制请求的流程、辅助处理结果的显示;javabean用来保存用户在JSP页面中的输入数据,他用来方便的向Action传递用户输入数据。
3.3 THE CONTROLLER
Struts用org.apache.struts.action.ActionServlet去实现controller的功能。这个servlet接收所有JSP页面发送的请求,根据一份配置文件得到处理相应用户请求的Action,并调用Action去处理用户的请求。当Action处理结束后,ActionServlet接受处理结果,并根据同样的配置文件将处理结果发送当相应的JSP页面。
4 Struts主要技术介绍
4.1 相关技术
学习Struts,首先要了解一下以下相关技术。(有些部分只提供相关的资料链接,不做讲解)。
4.1.1 JavaBeans
大多数JavaBeans是由JavaBeans来编写的.
· The JavaBeans Component Architecture Documentation page at
java.sun.com, including a link to download the JavaBeans 1.01 Specification
· The JavaBean Trail in the Java Tutorial
· JavaBeans Components in JSP Pages in the Java Web Services Tutorial
4.1.2 反射和内省
反射机制是一种决定一个对象哪些成员域和成员方法被采用的过程。内省技术是反射机制的一种特殊机制,Structs使用内省技术转换HTTP参数为JavaBean的属性,读取JavaBean属性装配HTML字段。
· The Reflection Trail
· Chapter 8 of the JavaBeans API Specification
4.1.3 属性文件和ResourceBundles
4.1.3.1 属性文件
属性文件主要用来设置程序属性,属性文件的后缀名为.properties,属性文件的格式类似于以下内容:
book=my computer book
pages=120
authors=zhf
seminar=12
4.1.3.2 使用属性文件
java.util包中Properties类用来管理一个Key/value对,Properties类提供了以下方法:
load()方法:Loading key/value pairs into a Properties object form a Stream 从一个输入流中加载
getProperty()方法:Retrieving a value from its key 通过关键字来获得值
list()方法:Listing the keys and their values 列举
Save()方法:Saving the properties to a stream 保存属性
具体例子如下
import java.util.*;
import java.io.*;
public class useProperties
{
public static void main(String[] args)
{
try{
Properties defaultProps=new Properties();
FileInputStream file=new FileInputStream("test.properties");
defaultProps.load(file);
file.close();
defaultProps.list(System.out);
System.out.println("getProperty(String key,Stringdefault)= "
+defaultProps.getProperty("book"));
FileOutputStream out=new FileOutputStream("appProperties");
defaultProps.store(out,"-----no comment--");
out.close();
}catch(Exception e)
{
e.printStackTrace();
}
}
}
4.1.3.3 使用本地化数据
使用本地化数据,需要建立多个属性文件,假设我们系统中需要支持德文和法文,我们的默认属性文件为LabelsBundle.properties文件,那么我们需要建立德文和法文所对应的属性文件:
LabelBundle_de.properties
LabelBundle_fr.properties
# LabelsBundle.properties 内容
s1 = computer
s2 = disk
s3 = monitor
s4 = keyboard
# LabelsBundle_de.properties内容
s1 = Computer
s2 = Platte
s3 = Monitor
s4 = Tastatur
# LabelsBundle_fr.properties内容
s1 = Computerfr
s2 = Plattefr
s3 = Monitorfr
s4 = Tastaturfr
4.1.3.4 ResoureBundle和Locale
通过ResourceBundle结合Locale对象可以选择属性文件:
下面我们给一个具体的例子
import java.util.*;
import java.io.*;
public class ResourceBundleDemo{
public static void main(String[] args)
{
//采用了德国设置
Locale currentLocal=Locale.GERMAN;
ResourceBundle labels=ResourceBundle.getBundle("LabelsBundle",currentLocal);
String myValue=labels.getString("s2");
System.out.println(" Local=GERMAN ; S2= "+myValue);
//采用了法国设置
currentLocal=Locale.FRENCH;
labels=ResourceBundle.getBundle("LabelsBundle",currentLocal);
myValue=labels.getString("s2");
System.out.println(" Local= FRENCH ; S2= "+myValue);
}
}
更多的内容可以查看:
· Using Properties to Manage Program Attributes in The Java Tutorial
· About the ResourceBundle Class in the Java Tutorial
4.1.4 JSP和JSP标签库
Jsp中提供了一些标准的标签:
useBean,setProperty/getProperty,include,forward,plugin。
使用例子如:
<jsp:useBean id=”bookname” scope=”page” class=”test.book”/>
这些标准的标签,为操作JavaBean和相应请求等提供便利,除此之外,JSP技术允许我们自己封装特有的标签,来简化应用程序开发。有经验的开发者可以利用标签处理表单,访问数据库或其他企业服务(如e-mail或目录服务等)。
4.1.4.1 标签的主要技术
可以在JSP页面中设置标签的参数。
可以访问JSP页面中所有的对象。
可以获得JSP页面的Response对象。
标签之间互相通讯。
标签可以被嵌套,实现标签的多层使用。
4.1.4.2 标签的使用
为了能够在jsp页面中使用一个标签,我们需要变现一个实现了TagSupport类的java程序,然后通过tld文件,定义该标签的属性,然后通过web.xml声明这个tld文件,最后才可以在JSP页面中使用标签的。
下面我还是根据例子来简单讲一下
详细代码下src/taguse目录下。
4.1.4.2.1 定制标签类
package com.zhfelva.tag;
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;
import java.io.*;
/**
* 一个显示当前时间的标签
*/
public class CurrentTimeTag extends TagSupport {
public int doStartTag() {
try {
JspWriter out = pageContext.getOut();
java.util.Date dt = new java.util.Date(System.currentTimeMillis());
out.print(dt.getHours()+":"+dt.getMinutes()+":"+dt.getSeconds());
} catch(IOException ioe) {
System.out.println("Error in CurrentTimeTag: " + ioe);
}
return(SKIP_BODY);
}
}
4.1.4.2.2 编写标签定义文件
放于\WEB-INF\taglib\mytaglib.tld
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN"
"http://java.sun.com/j2ee/dtds/Web-jsptaglibrary_1_1.dtd">
<!-- a tag library descriptor -->
<taglib>
<tlibversion>1.0</tlibversion>
<jspversion>1.1</jspversion>
<shortname>current time</shortname>
<uri></uri>
<info>
A tag library for show current time
</info>
<tag>
<name>CurrentTime</name>
<tagclass>com.zhfelva.tag.CurrentTimeTag</tagclass>
<bodycontent>EMPTY</bodycontent>
<info>show current time</info>
</tag>
</taglib>
4.1.4.2.3 在web.xml中进行配置
一个网页应用程序要在web.xml中声明他要使用的标签库:
<?xml version="1.0" encoding="gb2312"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/j2ee/dtds/web-app_2.3.dtd">
<web-app>
<taglib>
<taglib-uri>
my-taglib
</taglib-uri>
<taglib-location>
/WEB-INF/taglib/mytaglib.tld
</taglib-location>
</taglib>
</web-app>
4.1.4.2.4 简单标签的使用
以上配置做好之后,就可以在JSP页面中使用标签了:
currenttime.jsp
<%@ page contentType="text/html;charset=gb2312" %>
<%@ taglib uri="my-taglib" prefix="mytag" %>
<HTML>
<HEAD>
<TITLE>显示当前时间 - JSP/TagLib</TITLE>
</HEAD>
<BODY>
<H1>显示当前时间 - JSP/TagLib</H1>
<mytag:CurrentTime />
</BODY>
</HTML>
Struts中真正将标签库应用了起来,大家可以从中看到标签库的强大功能。
更多的内容可以查看:
4.1.5 XML相关技术
这里,相关的内容非常多,而且很重要,相信大家也都熟悉XML技术,由于时间关系,这里就不做讲述了。
4.2 主要技术
4.2.1 Struts体系结构
控制:通过Struts体系图大家可以看到有一个XML文件Struts-config.xml,与之相关联的是Controller,在Struts中,承担MVC中Controller角色的是一个Servlet,叫ActionServlet。ActionServlet是一个通用的控制组件。这个控制组件提供了处理所有发送到Struts的HTTP请求的入口点。它截取和分发这些请求到相应的动作类(这些动作类都是Action类的子类)。另外控制组件也负责用相应的请求参数填充 Action From(通常称之为FromBean),并传给动作类(通常称之为ActionBean)。动作类实现核心商业逻辑,它可以访问java bean 或调用EJB。最后动作类把控制权传给后续的JSP 文件,后者生成视图。所有这些控制逻辑利用Struts-config.xml文件来配置。
视图:主要由JSP生成页面完成视图,Struts提供丰富的JSP 标签库: Html,Bean,Logic,Template等,这有利于分开表现逻辑和程序逻辑。
模型:模型以一个或多个java bean的形式存在。这些bean分为三类:Action Form、Action、JavaBean or EJB。Action Form通常称之为FormBean,封装了来自于Client的用户请求信息,如表单信息。Action通常称之为ActionBean,获取从ActionSevlet传来的FormBean,取出FormBean中的相关信息,并做出相关的处理,一般是调用Java Bean或EJB等。
流程:在Struts中,用户的请求一般以*.do作为请求服务名,所有的*.do请求均被指向ActionSevlet,ActionSevlet根据Struts-config.xml中的配置信息,将用户请求封装成一个指定名称的FormBean,并将此FormBean传至指定名称的ActionBean,由ActionBean完成相应的业务操作,如文件操作,数据库操作等。每一个*.do均有对应的FormBean名称和ActionBean名称,这些在Struts-config.xml中配置。
4.2.2 Struts的基本组件包
整个struts大约有15包,近200个类所组成,而且数量还在不断的扩展。在此我们不能一一介绍,只能列举几个主要的简要的介绍一下。下表说明了目前struts api中基本的几个组件包,包括action,actions,taglib。图片(5)则显现了这几个组件包之间的关系。其中action是整个struts framework的核心
org.apache.struts.action |
基本上,控制整个struts framework的运行的核心类、组件都在这个包中,比如我们上面提到的控制器ActionServlet,Action,ActionForm,ActionMapping等等。struts1.1比1.0多了 DynaActionForm 类。增加了动态扩展生成FormBean功能 |
org.apache.struts.actions |
这个包是主要作用是提供客户的http请求和业务逻辑处理之间的特定适配器转换功能,而1.0版本中的部分动态增删FromBean的类,也在struts1.1中被Action包的DynaActionForm组件所取代 |
org.apache.struts.taglib |
这不是一个包,而是是一个客户标签类的集合。下面包括Bean Tags,HTML Tags,Logic Tags,Nested Tags,Template Tags这几个用于构建用户界面的标签类。 |
对于Struts 如何控制、处理客户请求,让我们通过对struts的四个核心组件介绍来具体说明。这几个组件就是:ActionServlet。Action Classes,Action Mapping(此处包括ActionForward),ActionFrom Bean。
4.2.3 Struts ActionServlet
ActionServlet继承自javax.servlet.http.HttpServlet类,其在Struts framework中扮演的角色是控制器,参看上面的“Struts体系图”。控制器ActionServlet主要负责将客户的HTTP请求信息组装后,根据配置文件的指定描述,转发到适当的处理器。 按照Servelt的标准,所有得Servlet必须在web配置文件(web.xml)声明。同样,ActoinServlet必须在Web Application配置文件(web.xml)中描述,有关配置信息,后面将会介绍。
当用户向服务器端提交请求的时候,实际上信息是首先发送到控制器ActionServlet,一旦控制器获得了请求,其就会将请求信息传交给一些辅助类(help classes)处理。这些辅助类知道如何去处理与请求信息所对应的业务操作。在Struts中,这个辅助类就是org.apache.struts.action.Action。通常开发者需要自己继承Aciton类,从而实现自己的Action实例。
4.2.4 Struts Action Classes
public ActionForward execute(ActionMapping mapping,
ActionForm form,
javax.servlet.ServletRequest request,
javax.servlet.ServletResponse response)
throws java.io.IOException,javax.servlet.ServletException
|
Action类所作的工作,正如它的名称一样,就是具体的业务操作。Action类中最为常用的是execute()方法。
当Controller收到客户的请求的时候,就会将请求转移到一个Action实例,然后会调用这个Action实例的execute()方法。Struts Framework为应用系统中的每一个Action类只创建一个实例。所有的用户都使用这一个实例, Action 类运行在一个多线程的环境中。
注意,客户自己继承的Action子类,必须重写execute()方法,因为Action类在默认情况下是返回null的。
4.2.5 Struts Action Mapping
上面讲到了一个客户请求是如何被控制器转发和处理的,但是,控制器如何知道什么样的信息转发到什么样的Action类呢?这就需要一些与动作和请求信息相对应的映射配置说明。在struts 中,这些配置映射信息是存储在特定的XML文件(struts-config.xml)。
<action-mappings>
<action path="/logonAction"
type="com.test.LogonAction"
name="LogonForm"
scope="request"
input="logoncheck.jsp"
validate="false">
<forward name="welcome" path="/welcome.jsp"/>
<forward name="failure" path="/logon_failure.jsp "/>
</action>
</action-mappings>
|
这些配置信息在系统启动的时候被读入内存,供struts framework在运行期间使用。在内存中,每一个<action>元素都与org.apache.struts.action.ActionMapping类的一个实例对应。下表就显示了一个登陆的配置映射。
Path:这个属性用来和JSP页面中,调用<html:form>时的action属性相对应,它将JSP页面和处理这个JSP页面的Action对象对应起来。
Type: 对应的Action子类的完整类名。
Name: 对应的ActionForm的名称。他与下面将描述的<form-bean>元素的name属性相应。
Scope:这个属性表示相对应的ActionForm bean 的scope属性。它的值可以是“page”、“request”、“session”和“application”。分别对应java bean的“page”、“request”、“session”和“application”属性。
Input:这个属性表示如果对应的ActionForm的validate方法返回值的ActionErrors非空,即ActionForm的属性没有通过校验,则跳转到当前的页面。
Validate: 是否调用FormBean的validate()方法来验证,关闭它之后就不会报出错误信
息了。True表示需要调用validate方法;false表示不需要调用validate方法。
forward:定义可能的跳转路径。Name属性表示Action类的execute方法中,生成的返回结果时的参数;path表示将要跳转到的页面的路径。
<form-beans>
<form-bean name="LoginForm" type="com.test.LoginForm"/>
</form-beans> |
上面的配置表示:当可以通过/logonAction.do提交请求信息的时候,控制器将信息委托com.test.LogonAction处理。调用LogonAction实例的execute()方法。同时将Mapping实例和所对应的LogonForm Bean信息传入。其中name=LogonForm,使用的form-bean元素所声明的ActionForm Bean。有关form-bean的声明如下显示。
<form-bean>有两个属性:
name :这个ActionForm的名字,他与被JSP页面中的<HTML:form>元素的name属性应该是相同的。比如,如果在一个JSP页面中需要生成一个ActionForm对象,这个对象的名字(就是name属性)是“LoginForm”,则JSP页面中的<HTML:form>元素的name属性也应该是“LoginForm”。
Type :这个ActionForm对象的完整类名。这个属性和JSP页面中的<HTML:form>元素的type属性是相对应的。
在此稍稍说一下有关global-forwards的概念。其在配置文件中描述了整个应用系统可以使用的ActionForward,而不是仅仅是一个特定的Action。
<global-forwards>元素用来表示全局的跳转页面。和<action>元素一样,他有无数个<forward>元素。当一个Action对象的execute方法执行完毕以后,如果他返回的ActionForward对象没有在这个<action>元素的<forward>子元素中有对应值的话,他将要查找<global-forwards>中的<forward>元素,并跳转到相应页面。
<global-forwards>
<forward name="logout" path="/logout.do"/>
<forward name="error" path="/error.jsp"/>
</global-forwards> |
<message-resources parameter="test.ApplicationResources"/> |
前面我们讲过Struts采用属性文件来保存应用程序的信息,那么,Struts如何知道属性文件的路径呢,也在struts-config.xml文件来配置:
<message-resource>元素用来表示ApplicationResources.properties文件的位置。这个元素有一个属性――parameter,这个属性用来表示ApplicationResources.properties文件的存放地点,但有意思的是,他是用一个类名来来表示存放路径的。比如“com. ApplicationResources”是表示存放在WEB-INF/classes / com 路径下面的ApplicationResources.properties文件。上图表示的文件路径为WEB-INF/classes /test/ApplicationResources.properties。
注意:以上所述的这些元素在struts-config.xml文件中的位置也是有先后顺序的。它们的顺序是:
<form-beans>
< global-forwards >
<actions>
< message-resources >
4.2.6 Struts ActionForm Bean
在上面讲解ActionServlet,Action Classes和Action Mapping的时候,我们都提到了ActionForm Bean的概念。ActionForm的主要功能就是为Action的操作提供提交表单相映射的数据。
对于每一个客户请求,Struts framework在处理ActionForm的时候,一般需要经历如下几个步骤:
(1)检查Action的映射,确定Action中已经配置了对ActionForm的映射
(2)根据name属性,查找form bean的配置信息
(3)检查Action的formbean的使用范围,确定在此范围下,是否已经有此form bean的实例。
(4)假如当前范围下,已经存在了此form bean的实例,而是对当前请求来说,是同一种类型的话,那么就重用。
(5)否则,就重新构建一个form bean的实例
(6)form bean的reset()方法备调用
(7)调用对应的setter方法,对状态属性赋值
(8)如果validatede的属性北设置为true,那么就调用form bean的validate()方法。
4.3 例子讲解
在这一部分,我将根据一个简单的例子去详细的介绍一下struts框架的具体用法。
4.3.1 环境安装
4.3.1.1 利用Jbuilder8.0 使用Struts 1.1(版本)
目前Jbuilder中默认带的都是struts1.0版本,我们使用的是struts1.1版本,所以
需要手动的配置相关的类库
第一步:Struts1.1版本的获得
可以通过访问jakarta.apche.org的方式来下载,也可以从我机器的共享目录拷贝:
IP:150.18.17.150 或机器名zhf
User: guest
PWD: 空
内容: src文件夹下 有 Jarkarta-struts-1.1-rc1
Jarkarta-struts-1.1-rc1-src
Example_struts(例子文件源代码,可以用Jbuilder直接打开)
Properties(属性文件使用例子)
Taguse(taglib例子)
还有一些资料。
第二步: Jbuilder配置Struts1.1
首先将Struts1.1文件(包括源码)拷贝至jbuilder/thirdparty目录下:
打开jbuilder,选择tools/configure libraries,在弹出的窗口上点击new 按钮
Name :struts1.1
Location :Jbuilder
点击 Ok,回到刚才的界面,你会看到多出的一项struts1.1,选中它,在右边的class标签中点击Add按钮,将所带的所有jar包添加进去,最后的效果如下图:
然后选择FrameWork标签,在其中的Framework上选择Struts即可。
(这里Jbuilder会自动识别版本的)。
4.3.1.2 利用Jbuilder创建支持Struct1.1的工程:
首先建立一个jbuilder工程文件,名称可以自己定,这里我使用的easyuse
然后建立一个war文件,名称可以自己定,这里我使用的easyuse,注意在下面的选项中使用Struts1.1(Struts1.1)Frameworks
这时程序的项目浏览器内容如下
我们可以看到一个Struts1.1节点出现在树形图中,证明你前面的操作是正确的。
4.3.1.3 利用Jbuilder支持的Stucts对象创建向导:
当我们点击新建按钮之后,我们可以看到在 Web标签下的其他对象。
Struts Converter
ActionForm
Action
JSP from ActionForm
大家可以跟着向导一步一步来操作。
4.3.2 程序编写
4.3.2.1 任务描述。
createBook.jsp----输入一本书的标题和页码。
bookview.jsp---正常运转之后,此界面将会获得createBook.jsp传来的title参数。
再次提交之后,又回到了creatbook.jsp界面,一个循环过程。
4.3.2.2 ActionForm类
为了便于讲述,我在讲解内容写入代码中。
package test;
import java.util.*;
import org.apache.struts.action.*;
import org.apache.struts.validator.ValidatorForm;
import javax.servlet.http.*;
public class BookActionForm extends ActionForm {
//这里要求 所有的自己编写的FormBean必须继承ActionForm
private String title="";
private int pages=0;
//这里的两个私有属性字段,对应了createBook.jsp中的两个文本框,Struts会自动给它们赋
//值的
public void setTitle(String title)
{ this.title=title;}
public String getTitle()
{ return this.title;}
public void setPages(int pages)
{ this.pages=pages;}
public int getPages()
{ return this.pages;}
//Stuts会自动调用ActionForm的validate()方法,来对输入信息进行校验。
// validate()方法返回为ActionErrors,这如java的Exception处理机制。
public ActionErrors validate(ActionMapping actionMapping, HttpServletRequest httpServletRequest)
{
ActionErrors errors =new ActionErrors();
if((title==null)||(title.length()<3))
{
errors.add("Title", new ActionError("error.book.title"));
}
if(pages<1)
{
errors.add("Page",new ActionError("error.book.page"));
}
return errors;
}
public void reset(ActionMapping actionMapping, HttpServletRequest httpServletRequest) {
title = null;
pages = 0;
}
}
4.3.2.3 Struts-config.xml
这是Struts核心文件,Struts-config.xml集中了所有页面的导航定义。对于大型的WEB项目,通过此配置文件即可迅速把握其脉络,这不管是对于前期的开发,还是后期的维护或升级都是大有裨益的。掌握Struts-config.xml是掌握Struts的关键所在。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.1//EN" "http://jakarta.apache.org/struts/dtds/struts-config_1_1.dtd">
<struts-config>
//FormBean的声明
<form-beans>
<form-bean name="bookActionForm"
type="test.BookActionForm" />
</form-beans>
//公共跳转
<global-forwards>
<forward name="bookCreated" path="/bookview.jsp"/>
<forward name="first" path="/createBook.jsp"/>
</global-forwards>
//action申明
<action-mappings>
<action path="/createBook"
type="test.BookAction"
attribute="bookActionForm"
name="bookActionForm"
scope="request"
validate="true"
input="/createBook.jsp" />
</action-mappings>
//属性文件声明
<message-resources parameter="test.ApplicationResources"/>
</struts-config>
4.3.2.4 Action类
package test;
import org.apache.struts.action.*;
import javax.servlet.http.*;
public class BookAction extends Action {
//这里要求 所有的自己编写的Action子类 必须继承Action
public ActionForward execute(ActionMapping actionMapping, ActionForm actionForm, HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) {
System.out.println("Start perform("+actionForm+").....");
//我们首先从request中获得参数
String title=httpServletRequest.getParameter("title");
String strPages=httpServletRequest.getParameter("pages");
System.out.println("getParameter title :"+title);
System.out.println("getParameter Pages:"+strPages);
System.out.println("run in this ----");
//我们再从FormBean中获得参数
title=((BookActionForm)actionForm).getTitle() ;
strPages=""+ ((BookActionForm)actionForm).getPages() ;
System.out.println(" after BookActionForm ");
System.out.println("BookActionForm title :"+title);
System.out.println("BookActionForm Pages:"+strPages);
//跳转
return actionMapping.findForward("bookCreated");
}
}
4.3.2.5 应用程序属性文件的使用
在classes/test 目录下创建一个ApplicationResources.properties的文件(此路径在strut-config.xml中定义),打开它,内容如下
index.title=Struts 简单应用
index.content=这是Struts的一个简单应用
error.book.title=<li>书名最少要有3个字符</li>
error.book.page=<li>一本书的页数最少要大于1页</li>
errors.header=<h3><font color="red">错误<UL>
errors.footer=</UL></font><HR>
4.3.2.6 createBook.jsp页代码
<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
<%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %>
<html:html locale="true">
<head>
<title>
//利用 bean前缀的标签, key为属性文件的关键字。
<bean:message key="index.title"/>
</title>
</head>
<body bgcolor="#ffffff">
<html:errors/>
<h1><bean:message key="index.content"/></h1>
// createBook.do表示该请求交给了控制起来处理,然后拆分字符串,分解出 createBook,
// 这就是实际的请求。
<html:form action="createBook.do" method="GET">
Title<html:text property="title"/><br/>
Pages<html:text property="pages"/><br/>
<html:submit property="submit"/>
</html:form>
</body>
</html:html>
4.3.2.7 bookview.jsp页代码
<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean"%>
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html"%>
<%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic"%>
<html:html locale="true">
<head>
<html:base/>
<title>
<bean:message key="index.title"/>
</title>
</head>
<body bgcolor="white">
<h1><bean:message key="index.content"/></h1>
<html:form action="createBook" method="GET">
title<html:text property="title"/><br/>
<html:submit property="submit"/>
</html:form>
</body>
</html:html>
4.3.2.8 错误处理:
前面的流程已经实现了,下面讲一下它的错误处理机制。
这个例子程序中,需要用户输入标题和页码。
当标题的字符数小于3时和页数小于1时都是不允许的。
ActionForm为接收数据的类,它是错误产生的源头:
public ActionErrors validate(ActionMapping actionMapping, HttpServletRequest httpServletRequest) {
ActionErrors errors =new ActionErrors();
if((title==null)||(title.length()<3))
{
//书名的字符数太少了
errors.add("Title", new ActionError("error.book.title"));
}
if(pages<1)
{
//页数不能小于1
errors.add("Page",new ActionError("error.book.page"));
}
return errors;
}
错误提示的描述 applicationResource.properties
error.book.title=<li>书名最少要有3个字符</li>
error.book.page=<li>一本书的页数最少要大于1页</li>
errors.header=<h3><font color="red">错误<UL>
errors.footer=</UL></font><HR>
对错误的选择处理
createBook.jsp中的处理
<html:errors/>
<html:errors property="Title"/>
<html:errors property="Page"/>