`
zengshaotao
  • 浏览: 752476 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Struts1详解

 
阅读更多

Struts学习文档问题: 1,STRUTS到底是什么?为什么它曾经能够成为框架的领导者? 2,STRUTS到底包含了那些内容?其中的核心内容有哪些?
3,STRUTS的应用领域有哪些?他为何能够胜任这个领域?总结:
(个人总结:其实要学好一门技术,首先你必须要喜欢它,而喜欢它你却必须要了解他,而了解他你必需要知道它。)今天主要的目标有以下这些:
1,了解STRUTS的基本结构和原理。 2,如何去使用STRUTS所带给我们的帮助。 3,如何解决平常所在STRUTS中遇到的一些问题。
4,如何去加深了解STRUTS。说明:下文用<1><2><3><4>标示的知识点分别为与上文所述目标一一对应。
1. struts的实现机制 <1> struts实质上就是在JSP
MODEL2的基础上实现的一个MVC框架。在struts框架中,模型由实现业务逻辑的JAVABEAN或EJB组件构成,控制器由ACTIONSERVLET和ACTION
来实现,视图由JSP文件构成。 例如:当ACTIONSERLET接受到一个客户请求时,将执行如下流程:
<1>检索和用户请求匹配的ActionMapping实例,如果不存在,就返回用户请求路径无效信息。
<2>如果ActionForm实例不存在,就创建一个ActionForm对象,把客户提交的表单数据保存到ActionForm对象中。
<3>根据配置信息决定是否需要表验证。如果需要验证,就调用ActionForm的validate()方法。
<4>如果ActionForm的validate()方法返回null或返回一个不包含ActionMessage的ActionErrors对象,就表示表单验证成功。
<5>ActionServlet根据ActionMapping实例包含的映射信息决定将请求转发给那个Action。如果响应的Action实例不存在,就先创建这个实例,然后调用Action的execute()方法。
<6>Action的execute()方法返回一个ActionForward对象,ActionServlet再把客户请求转发个ActionForward对象指向的jsp组件。
<7>ActionForward对象指向的jsp组件生成动态网页,返回给客户。
(注意<3>:对于以上流程(4),如果ActionForm的validate()方法返回一个包含一个或多个ActionMessage的ActionErrors对象,就表示表单验证失败,此时ActionServlet将直接把请求转发给包含用户提交表单的jsp组件。在这种情况下,不会再创建Action对象并调用Action的execute()方法。)
2. 数据验证 <2>
几乎所有和用户交互的应用都需要数据验证,而从头设计数据验证机制是很花时间的,幸运的是struts框架提供了现成的,易于使用的数据验证功能。
Struts数据验证可以分为两种类型:表单验证和业务逻辑验证。
表单验证:如果用户没有在表单中输入姓名就提交表单,将生成表单验证错误。该验证是由ActionForm
Bean的validate()方法来负责处理的。业务逻辑验证:如果用户在表单中输入的姓名为”accp”,按照本应用的业务规则,即不允许向”accp”打招呼,因此将生成业务逻辑错误。该验证是由Action的execute()方法来负责处理的。两种区别:表单验证通常只对用户输入的数据进行简单的语法和格式检查,而业务逻辑验证会对数据进行更为复杂的验证。在很多情况下,需要模型组件的介入,才能完成业务逻辑验证。(注意<3>:在Struts早期的版本中使用ActionError类来表示错误信息,ActionError类是ActionMessage的子类。Struts1.2将废弃ActionError,统一采用ActionMessage类来表示正常或错误消息。)
3.Action类的工作机制 <1>
所有的Action类都是org.apache.struts.action.Action的子类。Action子类应该覆盖父类的Execute()方法。当ActionForm
Bean被创建,并且表单验证顺利通过后,Struts框架就会调用Action类的Execute()的方法。 Execute()方法有如下参数:
ActionMapping: 包含了这个Action的配置信息,和struts-config.xml文件中的元素对应。
ActionForm:包含了用户的表单数据,当Struts框架调用execute() 方法时,ActionForm中的数据已经通过了表单验证。
HttpServletRequest:当前的http请求对象。
HttpServletResponse:当前的http请求对象。(注意<3>:在Action类中定义了getResources(HttpServletRequest
request)方法该方法返回当前默认的MessageResources对象,他封装了Resource
Bundle中的文本内容。例如:如果要读取消息key为”hello.jsp.title”对应的文本内容,可以调用MessageResource类的getMessage(String
key)方法,实例如下: MessageResources message=getResources(request); String
title=message.getMessage(“hello.jsp.title”); ) 4.创建存放常量的java文件 <4>
对于Struts应用,最好将一些常用的属性key常量定义在一个JAVA文件Constants.java中。把一些常量定义在Constants.java中可以提高Action类的独立性。当属性key常量值发生改变时,只需要修改Constants.java文件,而不需要修改Action类。例如:
Public Class Constants { Public static final String PENSON_KEY=”personbean”; }
Action的execute(…..) { Request.setAttribute(Constants .PENSON_KEY,”…”); }
5.配置struts应用 <3>
Struts应用采用两个基于xml的配置文件来配置应用。这两个配置文件为web.xml和struts-config.xml。web.xml适用于所有的java
Web应用,它是Web应用的发布描述文件,在Java Servlet规范中对它做了定义。对于Struts应用,在Web.xml文件中除了配置Java
Web应用的常规信息,还应该配置和Struts相关的特殊信息。 Struts-config.xml文件是Struts应用专有的配置文件。 5.1配置struts
的ActionServlet <3><4>
例如如下的web.xml配置部分(其实有很多IDE工具能够自动生成配置该文件,不过自动生成的配置文件也有不足之处:它不能够生成多个应用模块的配置,如下所示):
action
org.apache.struts.action.ActionServlet
config------------默认模块
/WEB-INF/struts-config.xml
config/moduleB---子模块
/WEB-INF/struts- moduleB.xml
action
*.do
index.jsp
分析:第一个元素的param-name属性为config,表示配置的是默认子应用模块,第二个元素的param-name属性为config/moduleB是以”config/”开头,表示非默认子应用模块。有两种办法进行子应用模块之间的切换。一种办法是使用全局或局部的元素,此时将元素的contextRelative属性设为true;还有一种办法是使用内置org.apache.struts.actions.SwitchAction类。以下是使用全局元素的例子:
也可以使用元素中的局部元素,例如:
.. … 此外,还可以使用org.apache.struts.actions.SwitchAction类,例如:
……
如果要从默认模块切换到ModuleB,可以采用与以下类似的URL: http://...../toModule.do?
prefix=moduleB&page=/index.do 如果要从ModuleB切换到默认模块,可以采用与以下类似的URL
http://...../toModule.do?prefix=&page=/index.do (提示:
不管应用中包含多少子应用,都只需要配置一个ActionServlet。有些开发者希望设置多个ActionServlet类来处理应用中的不同功能,其实这是不必要的,因为Servlet本身支持多线程。而且,目前的Struts框架只允许在应用中配置一个ActionServlet。)
5.1.1 ActionServlet,RequestProcessor,Action
在Struts框架中控制器的基础是ActionServlet。他负责从Struts配置文件中读取数据并初始化Struts应用程序的配置,并接受来自浏览器的各种请求,然后将请求处理指派给RequestProcessor类。由RequestProcessor类处理请求的所有特性。RequestProcessor首先选择Action类来执行请求。Action类用于连接视图层和模型层。
ActionServlet:org.apache.struts.action.ActionServlet类是一个Servlet,扩展了javax.servlet.HttpServlet,实现了servlet的生命周期的方法。所有的用户请求都先由ActionServlet来处理,然后再由ActionServlet把请求转发个其他组件。事实上ActionServlet的真正工作是借助RequestProcessor类实现的。
RequestProcessor:
RequestProcessor类处理ActionServlet接受到的所有请求。根据它的处理方式,可将每个请求分解为多个小任务,分别有不同的的方法执行。这就允许针对请求的各个单独部分自定义处理。
RequestProcessor 类的所有方法都有一个前缀process。他有以下方法: processPath() : 获取客户端请求的路径url。
processMapping(): 根据请求url获取所需的映射信息。 processRoles(): 检查用户的角色是否允许他访问请求的资源。
processActionForm(): 新建一个Form Bean或从请求会话中检索Form Bean。 ProcessForward():
处理元素的forward以匹配当前的请求路径。 processValidate():
调用Form Bean的validate()方法。 processPreprocess(): 告诉请求处理器调用此方法后,是否应继续处理请求。
processLocale(): 为请求选择一个语言环境。 processActionCreate(): 实例化当前ActionMapping指定的类的实例。
processActionPerform():
将调用action的perform()或execute()方法。(要开发自己的RequestProcessor类应遵循以下步骤: 1.
创建一个继承org.apache.struts.action.RequestProcessor的类,在该类中显示定义无参,方法体为空的构造方法。 2.
重写所需的方法,加入定制功能。 3.
修改配置文件struts-config.xml,在其中加入一个名为的元素,用以指定客户定制的RequestProcessor类。通过重写RequestProcessor的processPreprocess()方法可以轻松的解决中文转码问题。)
5.1.2 Struts的标签库这个知识点需要同学们多多练习,没有什么好讲的,希望同学们在以后的练习中多多练习就足够了。在这里就不说了。 5.1.3
Validator验证框架 Validator框架能够克服在ActionForm
Bean中进行数据验证的局限性,它允许为Struts应用灵活的配置验证规则,无需编程。Validatar框架主要依赖连个jar文件:jakarta-oro.jar和commons-validator.jar。
Validator框架不能用于验证标准的ActionForm类。如果要使用validator框架,应该采用ActionForm类的两个子类:DynaValidatorForm类和validator类。DynavalidatorForm和ValidatorForm类都实现了Validate()方法。Validate()方法调用验证框架的验证方法进行验证,如果验证失败,validate()方法最后返回ActionErrors对象。
5.2配置错误处理 <4>
尽管Struts框架提供了功能强大的通用错误处理机制,但不能保证处理所有的错误或异常。当错误发生时,如果Struts框架不能处理这种错误,就把错误抛给web容器。如果想避免直接让用户看到原始错误信息,可以在Web应用的发布描述文件中配置元素。例:
404
/common/404.jsp
500
/common/500.jsp
(分析:当web容器捕获到http404或hppt500错误时,将根据错误代码检索子元素,它用于指定java异常类。)
除上述方法外,也可以为Web容器捕获java异常配置元素,这时需要设置子元素,它用于指定java异常类。Web容器可能捕获如下异常:
RuntimeException 或 Error ServletException 或它的子类 IOException 或它的子类)
在元素中声明的java异常类必须是以上所例举的情况之一,以下代码演示了如何配置
javax.servlet.ServletException
/common/ ServletException.jsp <
exception-type >java.io.IOException /common/
IOException.jsp 通过上面的配置后,如果发生了ServletException异常,将返回ServletException.jsp网页。 5.3
Struts配置文件 <2><3><4>
Struts框架在启动时会读入基本配置文件,根据它来创建和配置各种Struts组件。Struts配置文件使得开发者可以灵活地组装和配置各个组件,提供了应用软件的可扩展性和灵活性,可以避免硬编码。Struts配置文件是基于xml的。例如strtus-config基本结构如下:
5.3.1
元素
元素是Struts配置文件的根元素,和它对应的配置类为org.apache.struts.config.ModuleConfig类。元素有8个子元素,他的DTD定义为
*:零到多个 ;+:一到多个 ?零到一个 5.3.2 元素
元素用来配置应用所需要的数据源。
元素包含零个,一个或多个子元素。
元素用于设置数据源的各项属性。例如:
配置好了数据源后,就可以在Action类中访问数据源。在org.apache.
Struts.action.Action类中定义了getDataSource(HttpRequest)方法,它用于获取数据源对象。部分代码如下:
Javax.sql.DataSource Ds; Java.sql.Connection Mycon; Try{
Ds=getDataSource(request); Mycon=dataSource.getConnection(); }catch(Exception
e){ ……… } 有时我们需要配置多个数据源,此时就需要为每一个数据源分配唯一的key值,通过该值来标识特定的数据源。例如:
在Action类中通过以下方式访问特定的数据源: DatasourceA
=getDataSource(request,”A”); DatasourceB =getDataSource(request,”B”); 5.3.3 元素
元素用来配置多个ActionForm Bean。 元素包含零个或多个 子元素。每个 元素又包含多个属性。以下是
元素的配置代码实例: 其实ActionForm Bean上面的这种写法并不是struts最理想的做法,按照struts框架官方的标准,使用
org.apache.struts.action.DynaActionForm(即动态的ActionForm Bean) 例如: 5.3.4
元素
元素用于配置异常处理。元素可以包含零个或者多个元素。
元素用来设置java异常和异常处理类org.apache.struts.action.ExceptionHander之间的映射。以下是配置
元素的实例:
5.3.5
元素
元素用来声明全局的转发关系。元素由零个或多个元素组成。元素用于把一个逻辑名映射到特定的url。例如:
如果a.jsp把请求转发给action1,可以使用以下代码: 或 5.3.6
元素
元素包含零个或者多个元素。元素描述了从特定的请求路径到响应的Action类的映射。
在元素中可以包含多个和子元素,他们分别配置局部的异常处理及请求转发仅被当前的Action所访问。(注意:元素的forward,include和type属性相互排斥,也就是说只能设置其中一项。Forward属性的作用和org.apache.struts.actions.ForwardAction类相同。Include属性的作用和
Org.apache.struts.actions.IncludeAction类相同。) 元素的部分属性如下:
Attribute: 设置和Action关联的ActionForm Bean在request或session范围的属性key. className:
和元素对应的配置元素。默认值为: org.apache.struts.action.ActionMapping。
roles:指定Action的配置参数。在Action类的execute()方法中,可以调用ActionMapping对象的getParameter()方法来读取该配置参数。
unknown: 如果此项为true,表示可以处理用户发出的所有无效的 Action URL。默认值为false; Validate:
指定是否要先调用ActionForm Bean的validate()方法。默认值为false;
Parameter:指定Action的配置参数。在Action类的execute()方法中,可以先调用ActionMapping对象的getParameter()方法来读取该配置参数。
5.3.7 元素 元素用于配置ActionServlet。
元素的属性如下: bufferSize:指定上载文件的输入缓冲大小。该属性为可选项,默认值为4096。
className:指定和元素对应的配置类,默认值为:
org.apache.struts.config.ControllerConfig。
contentType:指定响应结果的内容类型和字符编码。该属性为可选项,默认值为text/html。如果在Action和jsp网页中也设置了内容类型和字符编码,将会覆盖该属性。
Locale:指定是否把Locale对象保存到当前用户的Session中,默认值为false;
processorClass:指定负责处理请求的java类的完整类名。默认值为:
org.apache.struts.action.processorClass。如果把此项设置为自定义的类,那么应该保证该类扩展了org.apache.struts.action.RequestProcessor类。
tempDir:指定处理文件上载的零时目录。如果此项没有设置,将采用Servlet容器为Web应用分配的零时工作目录。
Nochache:如果为true,在相应结果中将加入特定的头参数:
Pragma,Cache-Control和Expires,防止页面被存贮在客户浏览器的缓存中,默认值为:flase。
如果应用包含多个子应用,可以在每个子应用的Struts配置文件中配置元素。这样,尽管这些子应用共享同一个ActionServlet对象,但是他们可以使用不同的RequestProcessor类。例如: 5.3.8
元素
元素用来配置Resource Bundle, Resource Bundle
用于存放本地化消息文件。属性如下:
className:和元素对应的配置类,默认值为:
org.apache.struts.config.MessageResourcesConfig。 factory:指定消息资源的工厂类。默认值为:
org.apache.struts.util.PropertyMessageResourceFactory类。 Key:指定Resource
Bundle存放在ServletContext对象中时采用的属性key。默认值为Globals.MESSAGES_KEY定义的字符串常量。只允许有一个Resource
Bundle采用默认的属性key。
Null:指定MessageResource类如何处理未知的消息key。如果此项为true,将返回空字符串。如果此项为false,将返回类似
“???global.lable.missing???”的字符串。该属性为可选项,默认是ture. Parameter:指定Resources
Bundle的消息资源文件名。例如:第一个元素采用了默认的key属性,同一个Struts配置文件只允许有一个默认的Resources
Bundle,所以第二个元素必须显示的设置key属性。许多Struts客户化标签都通过Bundle属性来指定Resource
Bundle,标签的bundle和元素的key属性匹配,例如
5.3.9 元素
元素用于配置Struts插件。只有className属性,该属性指定Struts插件类。插件类必须实现org.apache.struts.action.PlugIn接口。
元素可以包含零个或多个子元素。例如: 6.重新载如配置文件 <3><4>
当Web容器首次启动时,会加载并解析web.xml文件。默认情况下,在web容器运行时不会检测web.xml文件的更新并重新加载它。事实上,有许多Web容器由于安全的原因,不支持动态加载wen.xml文件的功能。同样,由于安全原因,Web容器在运行时也不会检测Struts配置文件的更新并重新加载它。不过有两种办法可以做到Web容器在运行时也检测Struts配置文件的更新并重新加载它。第一种:创建一个Struts
Action 类,他能够重新初始化ActionServlet( 为了提高安全性,最好对调用此Action类的权限进行限制)。在 ActionServlet
重新初始化时,能够把更新后的Struts配置文件的内容重新读到内存中。第二种:创建一个线程,他负责监视配置文件的lastModifiedTime属性。这个线程周期性地睡眠,每次睡眠一定时间,醒来户比较配制文件的当前lastModifiedTime属性和保存在内存中上一次的属性。如果这两个值不一样,说明文件被改动了,于是重新加载应用。与第一种相比,这种办法可以避免用户随意的重新加载应用。不过,第二种完全由线程来决定何时重新加载应用。
7.国际化国际化(I18N)指的是在软件设计阶段,就应该使软件支持多种语言和地区功能。这样,当需要在应用中添加对一种新的语言和国家的支持时,不需要对己有的软件返工,无需修改应用的程序代码。软件的本地化和国际化的区别:本地化意味着针对不同的语言的客户,开发出不同的软件版本;国际化意味着同一个软件可以面向使用各种不同的客户。如果一个应用支持国际化应该具备下列特征:
<1>当应用需要支持一种新的语言时,无需修改应用程序代码。 <2>文本,消息和图片从源程序代码中抽取出来,存贮在外部。
<3>应该根据用户的语言和地理位置,对与特定文化相关的数据,如日期,时间和货币,进行正确的格式化。 <4>支持非标准的字符集。
<5>可以方便快捷对应用做出调整,使它适应新的语言和地区。
无论是对WEB应用的本地化还是国际化,都会涉及字符编码转换问题。默认情况下,IE浏览器发送请求时采用“ISO-8859-1”字符编码,如果WEB程序要正确地读取用户发送的中文数据,则需要进行编码转换。一种方法是在处理请求前,先设置HTTPSERVELTRQUEST对象的字符编码:
Request.setCharacterEncoding(“gb2312”); 还有一种办法是对用户输入的请求数据进行编码转换: String
clientData=request.getParameter(“clientData”); If(clientData!=null)
clientData=new String(clientData.getBytes(“ISO-8859-1”),”gb2312”);
如果在XML文件中包含中文,可以将XML文件的字符编码为”GB2312”; 例如: 如果在Struts配置文件中对Resource Bundle做如下配置:
那么默认资源文件名为application.properties,它的存放位置为:
WEB-INF/classes/hello/application.properties。 Struts应用,子应用模块,Resource
Bundle和资源文件之间存在以下关系: <1>一个Struts应用可以有多个子应用模块,必须有且只有一个默认Resource Bundle。
<2>一个子应用模块可以有多个Resource Bundle,必须有且只有一个默认Resource Bundle。
<3>一个Resource Bundle可以有多个资源文件,必须有且只有一个默认资源文件。通过编程方式来访问Resource Bundle:例如:
在Action中的execute方法中 MessageResources messages=getResources(request); String
msg=messages.getMessage(locale,”hello.username.error”);
Org.apache,struts.util.MessageResources 的getMessage()方法有好几种重载的形式:
<1>getMessage(java.util.Locale locale,java.lang.String key);
根据参数指定的Locale检索对应的资源文件,然后返回和参数key对应的消息文本。 <2> getMessage(java.util.Locale
locale,java.lang.String key,java.lang.object[] args);
根据参数指定的Locale检索对应的资源文件,然后返回和参数key对应的消息文本,args参数用于替换复合消息文本中的参数 <3>
getMessage(java.lang.String key); 根据默认的Locale检索对应的资源文件,然后返回和参数key对应的消息文本。
Struts框架中的许多内在组件和Resource Bundle是绑定在一起的,如: <1>ActionMessage类和标签。
<2>Struts Bean标签库的标签。 <3>在Validator验证框架中访问Resource
Bundle。 <4>在声明型异常处理中访问Resource Bundle。
对临时资源文件进行编码转换:在JDK中提供的native2ascii命令,它能够实现字符编码转换。在DOS下执行以下命令,将生成按GB2312编码的中文资源文件application_zh_CN.properties:
Native2ascii -encoding gb2312 application.properties
application_zh_CN.properties。 (提示:
在同一个会话中,Struts框架仅读取HTTP请求的Locale信息一次,然后就把Locale对象保存在session范围内,因此在同一个会话中,Locale对象保持不变,选用的资源文件也不会变化。因此在上面的实验当中,把IE浏览器的语言选项设为英文后,应该重新打开一个IE浏览器,保证在一个新的会话中访问helloapp应用,这样才会看到英文网页。)

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics