??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲一区二区三区在线视频,亚洲精品无码av人在线观看,亚洲伊人久久大香线焦http://www.tkk7.com/fjpan2002/category/3569.htmlzh-cnWed, 28 Feb 2007 03:33:52 GMTWed, 28 Feb 2007 03:33:52 GMT60深入Struts 1.1(转自IBM)http://www.tkk7.com/fjpan2002/articles/21245.html勇敢的心勇敢的心Thu, 24 Nov 2005 02:55:00 GMThttp://www.tkk7.com/fjpan2002/articles/21245.htmlhttp://www.tkk7.com/fjpan2002/comments/21245.htmlhttp://www.tkk7.com/fjpan2002/articles/21245.html#Feedback0http://www.tkk7.com/fjpan2002/comments/commentRss/21245.htmlhttp://www.tkk7.com/fjpan2002/services/trackbacks/21245.html作ؓZMVC模式的Web应用最l典框架QStruts已经正式推出?.1版本Q该版本在以往版本的基上,提供了许多激动h心的新功能。本文就带你走qStruts 1.1L入地了解q些功能?/BLOCKQUOTE>

说明Q?/B>希望本文的读者能有一定的Struts使用基础?

Model 2

Struts是基于Model 2之上的,而Model 2是经典的MVCQ模型-视图Q控制器Q模型的Web应用变体Q这个改变主要是׃|络应用的特?-HTTP协议的无状态性引L。Model 2的目的和MVC一P也是利用控制器来分离模型和视图,辑ֈ一U层间松散耦合的效果,提高pȝ灉|性、复用性和可维护性。在多数情况下,你可以将Model 2与MVC{同h?/P>

下图表示一个基于Java技术的典型|络应用Q从中可以看出Model 2中的各个部分是如何对应于Java中各U现有技术的?/P>


在利用Model 2之前Q我们是把所有的表示逻辑和业务逻辑都集中在一P比如大杂烩似的JSPQ,有时也称q种应用模式为Model 1QModel 1的主要缺点就是紧耦合Q复用性差以及l护成本高?/P>

Struts 1.1 和Model 2

既然Struts 1.1是基于Model 2之上Q那它的底层机制也就是MVCQ下面是Struts 1.1中的MVC实现C意图:


图解说明Q其中不同颜色代表MVC的不同部分:U色Q控制器Q、Ԍ模型Q和l色Q视图)

首先Q控制器QActionServletQ进行初始化工作Q读取配|文Ӟstruts-config.xmlQ,Z同的Struts模块初始化相应的ModuleConfig对象。比如配|文件中的Action映射定义都保存在ActionConfig集合中。相应地有ControlConfig集合、FormBeanConfig集合、ForwardConfig集合和MessageResourcesConfig集合{?/P>

提示Q?/B>模块是在Struts 1.1中新提出的概念,在稍后的内容中我们将详细介绍Q你现在可以单地把模块看作是一个子pȝQ它们共同组成整个应用,同时又各自独立。Struts 1.1中所有的处理都是在特定模块环境中q行的。模块的提出主要是ؓ了解决Struts 1.0中单配置文g的问题?

控制器接收HTTPhQƈ从ActionConfig中找出对应于该请求的Action子类Q如果没有对应的ActionQ控制器直接请求{发给JSP或者静态页面。否则控制器请求分发至具体Actionc进行处理?/P>

在控制器调用具体Action的executeҎ(gu)之前QActionForm对象利用HTTPh中的参数来填充自己(可选步骤,需要在配置文g中指定)。具体的ActionForm对象应该是ActionForm的子cd象,它其实就是一个JavaBean。此外,q可以在ActionFormcM调用validateҎ(gu)来检查请求参数的合法性,q且可以q回一个包含所有错误信息的ActionErrors对象。如果执行成功,ActionForm自动这些参C息以JavaBeanQ一般称之ؓform beanQ的方式保存在Servlet Context中,q样它们可以被其它Action对象或者JSP调用?/P>

Struts这些ActionForm的配|信息都攑֜FormBeanConfig集合中,通过它们Struts能够知道针对某个客户h是否需要创建相应的ActionForm实例?/P>

Action很简单,一般只包含一个executeҎ(gu)Q它负责执行相应的业务逻辑Q如果需要,它也q行相应的数据检查。执行完成之后,q回一个ActionForward对象Q控制器通过该ActionForward对象来进行{发工作。我们主张将获取数据和执行业务逻辑的功能放到具体的JavaBean当中Q而Action只负责完成与控制有关的功能。遵循该原则Q所以在上图中我Action对象归ؓ控制器部分?/P>

提示Q?/B>其实在Struts 1.1中,ActionMapping的作用完全可以由ActionConfig来替代,只不q由于它是公共API的一部分以及兼容性的问题得以保留。ActionMapping通过l承ActionConfig来获得与其一致的功能Q你可以{同地看待它们。同理,其它例如ActionForward与ForwardConfig的关pM是如此?

下图l出了客L从发求到获得响应整个q程的图解说明?/P>


下面我们来详细地讨Z下其中的每个部分Q在q之前,先来了解一下模块的概念?/P>

模块

我们知道Q在Struts 1.0中,我们只能在web.xml中ؓActionServlet指定一个配|文Ӟq对于我们这些网上的教学例子来说当然没什么问题,但是在实际的应用开发过E中Q可能会有些ȝ。因多开发h员都可能同时需要修攚w|文Ӟ但是配置文g只能同时被一个h修改Q这栯定会造成一定程度上的资源争夺,势必会媄响开发效率和引v开发h员的抱怨?/P>

在Struts 1.1中,Z解决q个q行开发的问题Q提Z两种解决Ҏ(gu)Q?

  1. 多个配置文g的支?
  2. 模块的支?

支持多个配置文gQ是指你能够为ActionServlet同时指定多个xml配置文gQ文件之间以逗号分隔Q比如Struts提供的MailReader演示例子中就采用该种Ҏ(gu)?/P>

  <!-- Action Servlet Configuration -->
  <servlet>
	<servlet-name>action</servlet-name>
	<servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
	<init-param>
		<param-name>config</param-name>
		<param-value>/WEB-INF/struts-config.xml, /WEB-INF/struts-config-registration.xml</param-value>
	</init-param> 
	<load-on-startup>1</load-on-startup>
  </servlet>

q种Ҏ(gu)可以很好地解决修改冲H的问题Q不同的开发h员可以在不同的配|文件中讄自己的Action、ActionForm{等Q当然不是说每个开发h员都需要自q配置文gQ可以按照系l的功能模块q行划分Q。但是,q里q是存在一个潜在的问题Q就是可能不同的配置文g之间会生冲H,因ؓ在ActionServlet初始化的时候这几个文g最l还是需要合q到一L。比如,在struts-config.xml中配|了一个名为success?lt;forward>Q而在struts-config-registration.xml中也配置了一个同L<forward>Q那么执行v来就会生冲H?/P>

Zd解决q种冲突QStruts 1.1中引q了模块QModuleQ的概念。一个模块就是一个独立的子系l,你可以在其中q行L所需的配|,同时又不必担心和其它的配|文件生冲H。因为前面我们讲q,ActionServlet是将不同的模块信息保存在不同的ModuleConfig对象中的。要使用模块的功能,需要进行以下的准备工作Q?/P>

1、ؓ每个模块准备一个配|文?/P>

2、配|web.xml文gQ通知控制?/P>

军_采用多个模块以后Q你需要将q些信息告诉控制器,q需要在web.xml文gq行配置。下面是一个典型的多模块配|:


<init-param>
	<param-name>config</param-name>
	<param-value>/WEB-INF/struts-config.xml</param-value>
</init-param>
<init-param>
	<param-name>config/customer</param-name> 
	<param-value>/WEB-INF/struts-config-customer.xml</param-value>
</init-param>
<init-param> 
	<param-name>config/order</param-name>
	<param-value>/WEB-INF/struts-config-order.xml</param-value>
</init-param>

要配|多个模块,你需要在原有的一?lt;init-param>Q在Struts 1.1中将其对应的模块UCؓ~省模块Q的基础之上Q增加模块对应的<init-param>。其?lt;param-name>表示为config/XXX的Ş式,其中XXX为对应的模块名,<param-value>中还是指定模块对应的配置文g。上面这个例子说明该应用有三个模块,分别是缺省模块、customer和orderQ它们分别对应不同的配置文g?/P>

3、准备各个模块所需的ActionForm、Action和JSP{资?/P>

但是要注意的是,模块的出C同时带来了一个问题,卛_何在不同模块间进行{发?有两U方法可以实现模块间的{发,一U就是在<forward>Q全局或者本圎ͼ中定义,另外一U就是利用org.apache.struts.actions.SwitchAction?/P>

下面是一个全局的例子:


    ... 
    <struts-config>
	... 
	<global-forwards>
		<forward name="toModuleB"
			contextRelative="true"  
			path="/moduleB/index.do" 
		redirect="true"/>   
	... 
	</global-forwards>  
	...   
    </struts-config>

可以看出Q只需要在原有的path属性前加上模块名,同时contextRelative属性置为true卛_。此外,你也可以?lt;action>中定义一个类似的本地<forward>?/P>

  <action-mappings>
	<!-- Action mapping for profile form -->
	<action path="/login" 
	type="com.ncu.test.LoginAction"  
	name="loginForm"     
	scope="request"      
	input="tile.userLogin"
	validate="true">     
	<forward name="success" contextRelative="true" path="/moduleA/login.do"/> 
	</action> 
  </action-mappings>

如果你已l处在其他模块,需要{回到~省模块Q那应该cM下面q样定义Q即模块名ؓI?/P>

<forward name="success" contextRelative="true" path="/login.do"/>

此外Q你也可以用org.apache.struts.actions.SwitchActionQ例如:


    ...
    <action-mappings> 
	<action path="/toModule" 
	type="org.apache.struts.actions.SwitchAction"/>  
	...    
    </action-mappings>  
    ...

ActionServlet

我们首先来了解MVC中的控制器。在Struts 1.1中缺省采用ActionServletcL充当控制器。当然如果ActionServlet不能满你的需求,你也可以通过l承它来实现自己的类。这可以?WEB-INF/web.xml中来具体指定?/P>

要掌握ActionServletQ就必须了解它所扮演的角艌Ӏ首先,ActionServlet表示MVCl构中的控制器部分,它需要完成控制器所需的前端控制及转发h{职责。其ơ,ActionServlet被实Cؓ一个专门处理HTTPh的ServletQ它同时hservlet的特炏V在Struts 1.1中它主要完成以下功能Q?

  • 接收客户端请?
  • Ҏ(gu)客户端的URI请求映到一个相应的Actionc?
  • 从请求中获取数据填充Form BeanQ如果需要)
  • 调用Actioncȝexecute()Ҏ(gu)获取数据或者执行业务逻辑
  • 选择正确的视囑֓应客?

此外QActionServletq负责初始化和清除应用配|信息的d。ActionServlet的初始化工作在initҎ(gu)中完成,它可以分Z个部分:初始化ActionServlet自n的一些信息以及每个模块的配置信息。前者主要通过initInternal、initOther和initServlet三个Ҏ(gu)来完成?/P>

我们可以?WEB-INF/web.xml中指定具体的控制器以及初始参敎ͼ׃版本的变化以及Struts 1.1中模块概늚引进Q一些初始参数被废弃或者移入到/WEB-INF/struts-config.xml中定义。下面列出所有被废弃的参敎ͼ相应地在web.xml文g中也不鼓励再使用?/P>

  • application
  • bufferSize
  • content
  • debug
  • factory
  • formBean
  • forward
  • locale
  • mapping
  • maxFileSize
  • multipartClass
  • nocache
  • null
  • tempDir

ActionServletҎ(gu)不同的模块来初始化ModuleConfigc,q在其中以XXXconfig集合的方式保存该模块的各U配|信息,比如ActionConfigQFormBeanConfig{?/P>

初始化工作完成之后,ActionServlet准备接收客户h。针Ҏ(gu)个请求,Ҏ(gu)process(HttpServletRequest request, HttpServletResponse response)被调用。该Ҏ(gu)指定具体的模块,然后调用该模块的RequestProcessor的processҎ(gu)?/P>

protected void process(HttpServletRequest request, 
		HttpServletResponse response) 
		throws IOException, ServletException {

	RequestUtils.selectModule(request, getServletContext());        
	getRequestProcessor(getModuleConfig(request)).process(request, response);
}

RequestProcessor包含了Struts控制器的所有处理逻辑Q它调用不同的processXXXҎ(gu)来完成不同的处理。下表列出其中几个主要的Ҏ(gu)Q?/P>

Ҏ(gu) 功能
processPath 获取客户端的h路径
processMapping 利用路径来获得相应的ActionMapping
processActionForm 初始化ActionFormQ如果需要)q存入正的scope?/TD>
processActionCreate 初始化Action
processActionPerform 调用Action的executeҎ(gu)
processForwardConfig 处理Actionq回的ActionForward

ActionForm

对于ActionForm你可以从以下几个斚w来理解它Q?

  1. ActionForm表示HTTPH体中的数据Q可以将其看作是模型和视囄中介Q它负责保存视图中的数据供模型或者视图用。Struts 1.1文档中把它比作HTTP和Action之间的防火墙Q这体现了ActionFormh的过滤保护的作用Q只有通过ActionForm验证的数据才能够发送到Action处理?
  2. ActionForm是与一个或多个ActionConfig兌的JavaBeanQ在相应的action的executeҎ(gu)被调用之前,ActionForm会自动利用请求参数来填充自己Q初始化属性)?
  3. ActionForm是一个抽象类Q你必须通过l承来实现自qcR?

ActionForm首先利用属性的getter和setterҎ(gu)来实现初始化Q初始化完毕后,ActionForm的validateҎ(gu)被调用,你可以在其中来检查请求参数的正确性和有效性,q且可以错误信息以ActionErrors的Ş式返回到输入H体。否则,ActionForm被作ؓ参数传给action的executeҎ(gu)以供使用?/P>

ActionForm bean的生命周期可以设|ؓsessionQ缺省)和requestQ当讄为sessionӞ记得在resetҎ(gu)中将所有的属性重新设|ؓ初始倹{?/P>

׃ActionForm对应于HTTPH体Q所以随着面的增多,你的ActionForm会急速增加。而且可能同一cd面字段会在不同的ActionForm中出玎ͼq且在每个ActionForm中都存在相同的验证代码。ؓ了解册个问题,你可以ؓ整个应用实现一个ActionForm或者至一个模块对应于一个ActionForm?/P>

但是Q聚合的代h(hun)是复用性很差,而且隄护。针对这个问题,在Struts 1.1中提ZDynaActionForm的概c?/P>

DynaActionFormc?/B>

DynaActionForm的目的就是减ActionForm的数目,利用它你不必创徏一个个具体的ActionFormc,而是在配|文件中配置出所需的虚拟ActionForm。例如,在下表中通过指定<form-bean>的type?org.apache.struts.action.DynaActionForm"来创Z个动态的ActionForm--loginForm?/P>

<form-beans>
	<form-bean name="loginForm" type="org.apache.struts.action.DynaActionForm">  
		<form-property name="actionClass" type="java.lang.String"/>
		<form-property name="username" type="java.lang.String"/>
		<form-property name="password" type="java.lang.String"/> 
	</form-bean> 
</form-beans>

动态的ActionForm的用方法跟普通的ActionForm相同Q但是要注意一炏V普通的ActionForm对象需要ؓ每个属性提供getter和setterҎ(gu)Q以上面的例子而言Q我们需要提供getUsername() ?setUsername()Ҏ(gu)取得和设|username属性,同样地有一Ҏ(gu)法用于取得和讄password属性和actionClass属性?/P>

如果使用DynaActionFormQ它?yu)属性保存在一个HashMapcd象中Q同时提供相应的get(name) ?set(name)Ҏ(gu)Q其中参数name是要讉K的属性名。例如要讉KDynaActionForm中username的|可以采用cM的代码:


String username = (String)form.get("username")Q?

׃值存放于一个HashMap对象Q所以要记得对get()Ҏ(gu)q回的Object对象做强制性类型{换。正是由于这点区别,如果你在Action中非帔RJ地使用ActionForm对象Q徏议还是用普通的ActionForm对象?/P>

在Struts 1.1中,除了DynaActionForm以外Q还提供了表单输入自动验证的功能Q在包org.apache.struts.validator中提供了许多有用的类Q其中最常见的就是DynaValidatorFormcR?/P>

DynaValidatorFormc?/B>

DynaValidatorForm是DynaActionForm的子c,它能够提供动态ActionForm和自动表单输入验证的功能。和使用DynaActionFormcMQ你必须首先在配|文件中q行配置Q?/P>

<form-beans>
	<form-bean name="loginForm" type="org.apache.struts.validator.DynaValidatorForm"> 
		<form-property name="actionClass" type="java.lang.String"/>     
		<form-property name="username" type="java.lang.String"/> 
		<form-property name="password" type="java.lang.String"/>  
	</form-bean>
</form-beans>

同时要定义验证的插gQ?/P>

  <plug-in className="org.apache.struts.validator.ValidatorPlugIn">
	<set-property property="pathnames"  
	value="/WEB-INF/validator-rules.xml,  
	/WEB-INF/validation.xml"/>
  </plug-in>

其中的validator.xml和validator-rules.xml分别表示验证定义和验证规则的内容Q可以合q在一PQ比如针对上例中的DynaValidatorFormQ我们有如下验证定义Qvalidator.xmlQ:


<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE form-validation PUBLIC  
"-//Apache Software Foundation//DTD Commons Validator Rules Configuration 1.0//EN"  
"http://jakarta.apache.org/commons/dtds/validator_1_0.dtd">
<!--    Validation Rules    $Id: validation.xml-->

<form-validation>  
<!-- ========== Default Language Form Definitions ===================== -->
<formset>  
	<form name="loginForm">     
		<field property="username" depends="required, minlength,maxlength"> 
			<arg0   key="prompt.username"/>          
			<arg1   key="${var:minlength}" name="minlength" resource="false"/>       
			<arg2   key="${var:maxlength}" name="maxlength" resource="false"/>              
			<var>                
				<var-name>maxlength</var-name>    
				<var-value>16</var-value>         
			</var>          
			<var>      
				<var-name>minlength</var-name>     
				<var-value>3</var-value>         
			</var>       
		</field>     
		<field property="password" depends="required, minlength,maxlength" bundle="alternate">          
			<arg0   key="prompt.password"/>   
			<arg1   key="${var:minlength}" name="minlength" resource="false"/>          
			<arg2   key="${var:maxlength}" name="maxlength" resource="false"/>  
			<var>              
				<var-name>maxlength</var-name>     
				<var-value>16</var-value>        
			</var>          
			<var>      
				<var-name>minlength</var-name> 
				<var-value>3</var-value>       
			</var>        
		</field>    
	</form>   
</formset>
</form-validation>

从上q定义中Q我们可以看到对于字Dusername有三w证:required, minlength, maxlengthQ意思是该字D不能ؓI,而且长度??6之间。而validator-rules.xml文g则可以采用Struts提供的缺省文件。注意在<form-bean>中定义的form是如何与validation.xml中的form兌h的。最后,要启动自动验证功能,q需要将Action配置的validate属性设|ؓtrue?/P>


<action path="/login"  
type="com.ncu.test.LoginAction"
name="loginForm"          
scope="request"         
input="tile.userLogin"validate="true">

此时QStruts根据xml配置文g中的定义来检验表单输入,q将不符合要求的错误信息输出到页面。但是你可能会想Q这个功能虽然好Q可是什么检验都跑到服务器端执行Q效率方面和用户易用性方面是不是有些问题Q你可能会怀念v那简单的JavaScript客户端验证?/P>

不用担心Q在Struts 1.1中也支持JavaScript客户端验证。如果你选择了客L验证Q当某个表单被提交以后,Struts 1.1启动客户端验证,如果览器不支持JavaScript验证Q则服务器端验证被启动,q种双重验证机制能够最大限度地满各种开发者的需要。JavaScript验证代码也是在validator-rules.xml文g中定义的。要启动客户端验证,你必d相应的JSP文g中做如下讄Q?

  1. ?lt;html:form>增加onsubmit属?
  2. 讄Javascript支持

下表中列Z一JSP文g的示例代码,U字部分为Javascript验证所需代码?/P>

<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
<table bgcolor="#9AFF9A" cellspacing="0" cellpadding="10" border="1" width="100%">
	<tr>
	<td> 
	<table cellspacing="0" cellpadding="0" border="0" width="100%"> 
	<tr bgcolor="#696969"> 
		<td align="center">     
		<font color="#FFFFFF">Panel 3: Profile</font>  
		</td>
		</tr> 
	<tr>  
		<td><br> 
		<html:errors/>  
		<html:form action="/login.do" focus="username"  onsubmit="return validateLoginForm(this);">  
		<html:hidden property="actionClass"/>   
		<center>      
		<table>      
			<tr>        
			<td>UserName:</td>   
			<td><html:text property="username" size="20"/></td> 
			</tr> 
			<tr>  
			<td>Password:</td>   
			<td><html:password property="password" size="20"/></td>    
			</tr>  
			<tr>  
			<td colspan=2><html:submit property="submitProperty" value="Submit"/></td>     
		</table>   
		</center>  
		</html:form> 
		<html:javascript formName="loginForm" dynamicJavascript="true" staticJavascript="false"/>  
	
	<script language="Javascript1.1" src="staticJavascript.jsp"></script>  
	</td> 
	</tr> 
	</table>
	</td>
	</tr>
</table>

其中onsubmit的gؓ"return validateLoginForm(this);"Q它的语法ؓQ?/P>

return validate + struts-config.xml中定义的form-bean名称 + (this);

staticJavascript.jsp的内容ؓQ?/P>

<%@ page language="java" %>
<%-- set document type to Javascript (addresses a bug in Netscape according to a web resource --%>
<%@ page contentType="application/x-javascript" %>
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
<html:javascript dynamicJavascript="false" staticJavascript="true"/>


如果validator-rules.xml中定义的基本验证功能不能满你的需求,你可以自己添加所需的验证类型?/P>

Action

我们通过l承ActioncL实现具体的执行类。具体Actioncȝ功能一般都在executeQ以前是performҎ(gu)Q方法中完成Q其中主要涉及到以下几个斚wQ?

  1. 辅助ActionFormq行一些表单数据的查?
  2. 执行必要的业务逻辑Q比如存取数据库Q调用实体bean{?
  3. 更新服务器端的bean数据Q后l对象中可能会用到这些数据,比如在JSP中利用bean:write来获得这些数据?
  4. Ҏ(gu)处理l果军_E序的去处,q以ActionForward对象的Ş式返回给ActionServlet?

提示Q?/B>׃在Action和ActionForm中都可以实现验证Ҏ(gu)Q那么如何来安排它们之间的分工呢Q一般来_我们U着MVC分离的原则,也就是视囄的验证工作放在ActionForm来完成,比如输入不能为空Qemail格式是否正确Q利用ValidatorForm可以很轻村֜完成q些工作。而与具体业务相关的验证则攑օAction中,q样可以获得最大ActionForm重用性的可能?

前面我们提到q,我们d业务逻辑执行分离到单独的JavaBean中,而Action只负责错误处理和程控制。而且考虑到重用性的原因Q在执行业务逻辑的JavaBean中不要引用Q何与Web应用相关的对象,比如HttpServletRequestQHttpServletResponse{对象,而应该将其{化ؓ普通的Java对象。关于这一点,可以参考Petstore中WAF框架的实现思\?/P>

此外Q你可能q注意到execute与perform的一个区别:executeҎ(gu)单地掷出Exception异常Q而performҎ(gu)则掷出ServletException和IOException异常。这不是说Struts 1.1在异常处理功能方面弱化了Q而是Z配合Struts 1.1中一个很好的功能--宣称式异常处理机制?/P>

宣称式异常处?/SPAN>

和EJB中的宣称式事务处理概늱|宣称式异常处理其实就是可配置的异常处理,你可以在配置文g中指定由谁来处理ActioncM掷出的某U异常。你可以按照以下步骤来完成该功能Q?

  1. 实现org.apache.struts.action.ExceptionHandler的子c,覆盖executeҎ(gu)Q在该方法中处理异常q且q回一个ActionForward对象
  2. 在配|文件中配置异常处理对象Q你可以配置一个全局的处理类或者单独ؓ每个Action配置处理c?

下表定义了一个全局的处理类CustomizedExceptionHandlerQ它被用来处理所有的异常?/P>

<global-exceptions> 
<exception 
	handler="com.yourcorp.CustomizedExceptionHandler" 
	key="global.error.message" 
	path="/error.jsp"    
	scope="request"    
	type="java.lang.Exception"/>
</global-exceptions>

其中具体的参数含义,可以参考ExceptionHandler.java源文件?/P>

taglib

讲完了模型和控制器,接下来我们要涉及的是视图。视囄角色主要是由JSP来完成,从JSP的规范中可以看出Q在视图层可?折腾"的技术不是很多,主要的就是自定义标记库的应用。Struts 1.1在原有的四个标记库的基础上新增了两个标记?-Tiles和Nested?/P>

其中Tiles除了替代Template的基本模板功能外Q还增加了布局定义、虚拟页面定义和动态页面生成等功能。Tiles强大的模板功能能够ə面获得最大的重用性和灉|性,此外可以l合Tiles配置文g中的面定义和Action的{发逻辑Q即你可以将一个Action转发C个在Tiles配置文g中定义的虚拟面Q从而减页面的数量。比如,下表中的Action定义了一个{发\径,它的l点是tile.userMainQ而后者是你在Tiles配置文g中定义的一个页面?/P>

<!-- ========== Action Mapping Definitions ============================== -->
<action-mappings>  
<!-- Action mapping for profile form --> 
	<action path="/login"   
		type="com.ncu.test.LoginAction"      
		name="loginForm"    
		scope="request"     
		input="tile.userLogin"
		validate="true">     
		<forward name="success" path="tile.userMain"/>   
	</action> 
</action-mappings>

Tiles配置文gQtiles-defs.xml


<!DOCTYPE tiles-definitions PUBLIC 
"-//Apache Software Foundation//DTD Tiles Configuration//EN"       "http://jakarta.apache.org/struts/dtds/tiles-config.dtd">
<tiles-definitions>  
<!-- =======================================================  --> 
<!-- Master definitions                                       -->
<!-- =======================================================  --> 
<!-- Page layout used as root for all pages. --> 

<definition name="rootLayout" path="/tiles-layouts/rootLayout.jsp"> 
	<put name="titleString" value="CHANGE-ME"/>   
	<put name="topMenu" value="/tiles-components/topMenu.jsp"/> 
	<put name="leftMenu" value="/tiles-components/panel1.jsp"/>  
	<put name="body" value="CHANGE-ME"/>   
	<put name="footer" value="/tiles-components/footer.jsp"/> 
</definition> 

<!-- =======================================================  --> 
<!-- Page definitions 					-->  
<!-- =======================================================  --> 

<!-- User Login page --> 
<definition name="tile.userLogin" extends="rootLayout"> 
	<put name="titleString" value="User Login"/>  
	<put name="body" value="/src/userLogin.jsp"/> 
</definition>  
<!-- User Main page --> 
<definition name="tile.userMain" extends="rootLayout"> 
	<put name="titleString" value="User Main"/>  
	<put name="body" value="/src/userMain.jsp"/> 
</definition>
</tiles-definitions>

而Nested标记库的作用是让以上q些基本标记库能够嵌套用,发挥更大的作用?/P>

Commons Logging 接口

所谓的Commons Logging接口Q是指将日志功能的用与日志具体实现分开Q通过配置文g来指定具体用的日志实现。这样你可以在Struts 1.1中通过l一的接口来使用日志功能Q而不ȝ具体是利用的哪种日志实现Q有点于cMJDBC的功能。Struts 1.1中支持的日志实现包括QLog4JQJDK Logging APIQ?LogKitQNoOpLog和SimpleLog?/P>

你可以按照如下的方式来用Commons Logging接口Q可以参照Struts源文中的许多cd玎ͼQ?/P>

package com.foo;
// ...
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
//...
	public class Foo {    
	// ...    
	private static Log log = LogFactory.getLog(Foo.class);
	// ...    
	public void setBar(Bar bar) {       
		if (log.isTraceEnabled()) {         
			log.trace("Setting bar to " + bar);   
		}      
	this.bar = bar;   
	}
// ...
}

而开启日志功能最单的办法是在WEB-INF/classes目录下添加以下两个文Ӟ

commons-logging.properties文gQ?/P>

# Note: The Tiles framework now uses the commons-logging package to output different information or debug statements. 
Please refer to this package documentation to enable it. The simplest way to enable logging is to create two files in 
WEB-INF/classes:
# commons-logging.properties
# org.apache.commons.logging.Log=org.apache.commons.logging.impl.SimpleLog
# simplelog.properties
# # Logging detail level,
# # Must be one of ("trace", "debug", "info", "warn", "error", or "fatal").
#org.apache.commons.logging.simplelog.defaultlog=trace
org.apache.commons.logging.Log=org.apache.commons.logging.impl.SimpleLog

simplelog.properties文gQ?/P>

# Logging detail level,
# Must be one of ("trace", "debug", "info", "warn", "error", or "fatal").
org.apache.commons.logging.simplelog.defaultlog=fatal

q里我们采用的日志实现是SimpleLogQ你可以在simplelog.properties文g指定日志明细的别:traceQdebugQinfoQwarnQerror和fatalQ从trace到fatal错误U别来高Q同时输出的日志信息也越来越。而这些别是和org.apache.commons.logging.log接口中的Ҏ(gu)一一对应的。这些别是向后包含的,也就是前面的U别包含后面U别的信息?/P>
关于作?/SPAN>
王和?邮g地址Q?ok_winnerboy@sina.com

原文章地址Q?BR>http://www-128.ibm.com/developerworks/cn/java/l-struts1-1/


勇敢的心 2005-11-24 10:55 发表评论
]]>
վ֩ģ壺 Ʒþþ| ޾Ʒ޲߲| ҹavӰԺ| ˾þô߽| aƵƵ| 91޾Ʒ鶹| պݺݾþ͵͵ɫۺ| һ| ɫվѹۿ| ձϵ1ҳϵ| ձ˳ƵѲ| һëƬѿ| ҹƵվ | ƵĻȫ| ѹۿƵ| 뾫ƷӰ| av뾫ƷϼӰӰԺ| ޹ƷAAAƬ| aëƬȫ| ŷߴSUV| ҹþþþþ| С˵ר޴ɫУ԰| ޾ƷƷ벻| ŷղ| ƷѸþ| ޹av| 㶮ַѹ| þþƷձҰ| ߹ۿ| ޾Ʒ߹ۿ | ۺƵ| þ99ۺϾƷҳ| Ʒɫʹ| 99þþƷձһ | ޻߹ۿ| ĻƷƵ| ŷxxxxx| ܲƵ| ޸޵ | 9ᆱƷƵ| һĻ|