- 浏览: 308643 次
- 性别:
- 来自: 南昌
文章分类
最新评论
-
秋风扫落叶:
不错,学习了。shadow文件中记录的格式是什么?
/etc/passwd & /etc/shadow 详解 -
key232323:
重拾jstl——写得很好。我收藏下。
JSTL标签用法 -
zxl10059:
不错,非常简明扼要
Hibernate分页 -
Batmankwok:
很好,所见略同,
自定义组件MXML和as两种实现的方式和区别 -
Dxx23:
摘话回帖!
通过response对象的sendRedirec ...
response.sendRedirect方式的转向与RequestDispatcher的forward方法的比较
Struts是基于Model 2之上的,而Model 2是经典的MVC(模型-视图-控制器)模型的Web应用变体,这个改变主要是由于网络应用的特性--HTTP协议的无状态性引起的。Model 2的目的和MVC一样,也是利用控制器来分离模型和视图,达到一种层间松散耦合的效果,提高系统灵活性、复用性和可维护性。在多数情况下,你可以将Model 2与MVC等同起来。
下图表示一个基于Java技术的典型网络应用,从中可以看出Model 2中的各个部分是如何对应于Java中各种现有技术的。
在利用Model 2之前,我们是把所有的表示逻辑和业务逻辑都集中在一起(比如大杂烩似的JSP),有时也称这种应用模式为Model 1,Model 1的主要缺点就是紧耦合,复用性差以及维护成本高。
|
|
既然Struts 1.1是基于Model 2之上,那它的底层机制也就是MVC,下面是Struts 1.1中的MVC实现示意图:
图解说明:其中不同颜色代表MVC的不同部分:红色(控制器)、紫色(模型)和绿色(视图)
首先,控制器(ActionServlet)进行初始化工作,读取配置文件(struts-config.xml),为不同的Struts模块初始化相应的ModuleConfig对象。比如配置文件中的Action映射定义都保存在ActionConfig集合中。相应地有ControlConfig集合、FormBeanConfig集合、ForwardConfig集合和MessageResourcesConfig集合等。
提示:模块是在Struts 1.1中新提出的概念,在稍后的内容中我们将详细介绍,你现在可以简单地把模块看作是一个子系统,它们共同组成整个应用,同时又各自独立。Struts 1.1中所有的处理都是在特定模块环境中进行的。模块的提出主要是为了解决Struts 1.0中单配置文件的问题。
控制器接收HTTP请求,并从ActionConfig中找出对应于该请求的Action子类,如果没有对应的Action,控制器直接将请求转发给JSP或者静态页面。否则控制器将请求分发至具体Action类进行处理。
在控制器调用具体Action的execute方法之前,ActionForm对象将利用HTTP请求中的参数来填充自己(可选步骤,需要在配置文件中指定)。具体的ActionForm对象应该是ActionForm的子类对象,它其实就是一个JavaBean。此外,还可以在ActionForm类中调用validate方法来检查请求参数的合法性,并且可以返回一个包含所有错误信息的ActionErrors对象。如果执行成功,ActionForm自动将这些参数信息以JavaBean(一般称之为form bean)的方式保存在Servlet Context中,这样它们就可以被其它Action对象或者JSP调用。
Struts将这些ActionForm的配置信息都放在FormBeanConfig集合中,通过它们Struts能够知道针对某个客户请求是否需要创建相应的ActionForm实例。
Action很简单,一般只包含一个execute方法,它负责执行相应的业务逻辑,如果需要,它也进行相应的数据检查。执行完成之后,返回一个ActionForward对象,控制器通过该ActionForward对象来进行转发工作。我们主张将获取数据和执行业务逻辑的功能放到具体的JavaBean当中,而Action只负责完成与控制有关的功能。遵循该原则,所以在上图中我将Action对象归为控制器部分。
提示:其实在Struts 1.1中,ActionMapping的作用完全可以由ActionConfig来替代,只不过由于它是公共API的一部分以及兼容性的问题得以保留。ActionMapping通过继承ActionConfig来获得与其一致的功能,你可以等同地看待它们。同理,其它例如ActionForward与ForwardConfig的关系也是如此。
下图给出了客户端从发出请求到获得响应整个过程的图解说明。
下面我们就来详细地讨论一下其中的每个部分,在这之前,先来了解一下模块的概念。
|
|
我们知道,在Struts 1.0中,我们只能在web.xml中为ActionServlet指定一个配置文件,这对于我们这些网上的教学例子来说当然没什么问题,但是在实际的应用开发过程中,可能会有些麻烦。因为许多开发人员都可能同时需要修改配置文件,但是配置文件只能同时被一个人修改,这样肯定会造成一定程度上的资源争夺,势必会影响开发效率和引起开发人员的抱怨。
在Struts 1.1中,为了解决这个并行开发的问题,提出了两种解决方案:
- 多个配置文件的支持
- 模块的支持
支持多个配置文件,是指你能够为ActionServlet同时指定多个xml配置文件,文件之间以逗号分隔,比如Struts提供的MailReader演示例子中就采用该种方法。
<!-- 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> <!-- code sample is too wide --> </init-param> <load-on-startup>1</load-on-startup> </servlet> |
这种方法可以很好地解决修改冲突的问题,不同的开发人员可以在不同的配置文件中设置自己的Action、ActionForm等等(当然不是说每个开发人员都需要自己的配置文件,可以按照系统的功能模块进行划分)。但是,这里还是存在一个潜在的问题,就是可能不同的配置文件之间会产生冲突,因为在ActionServlet初始化的时候这几个文件最终还是需要合并到一起的。比如,在struts-config.xml中配置了一个名为success的<forward>,而在struts-config-registration.xml中也配置了一个同样的<forward>,那么执行起来就会产生冲突。
为了彻底解决这种冲突,Struts 1.1中引进了模块(Module)的概念。一个模块就是一个独立的子系统,你可以在其中进行任意所需的配置,同时又不必担心和其它的配置文件产生冲突。因为前面我们讲过,ActionServlet是将不同的模块信息保存在不同的ModuleConfig对象中的。要使用模块的功能,需要进行以下的准备工作:
1、为每个模块准备一个配置文件
2、配置web.xml文件,通知控制器
决定采用多个模块以后,你需要将这些信息告诉控制器,这需要在web.xml文件进行配置。下面是一个典型的多模块配置:
<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> |
要配置多个模块,你需要在原有的一个<init-param>(在Struts 1.1中将其对应的模块称为缺省模块)的基础之上,增加模块对应的<init-param>。其中<param-name>表示为config/XXX的形式,其中XXX为对应的模块名,<param-value>中还是指定模块对应的配置文件。上面这个例子说明该应用有三个模块,分别是缺省模块、customer和order,它们分别对应不同的配置文件。
3、准备各个模块所需的ActionForm、Action和JSP等资源
但是要注意的是,模块的出现也同时带来了一个问题,即如何在不同模块间进行转发?有两种方法可以实现模块间的转发,一种就是在<forward>(全局或者本地)中定义,另外一种就是利用org.apache.struts.actions.SwitchAction。
下面就是一个全局的例子:
... <struts-config> ... <global-forwards> <forward name="toModuleB" contextRelative="true" path="/moduleB/index.do" redirect="true"/> ... </global-forwards> ... </struts-config> |
可以看出,只需要在原有的path属性前加上模块名,同时将contextRelative属性置为true即可。此外,你也可以在<action>中定义一个类似的本地<forward>。
<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> |
如果你已经处在其他模块,需要转回到缺省模块,那应该类似下面这样定义,即模块名为空。
<forward name="success" contextRelative="true" path="/login.do"/> |
此外,你也可以使用org.apache.struts.actions.SwitchAction,例如:
... <action-mappings> <action path="/toModule" type="org.apache.struts.actions.SwitchAction"/> ... </action-mappings> ... |
|
|
我们首先来了解MVC中的控制器。在Struts 1.1中缺省采用ActionServlet类来充当控制器。当然如果ActionServlet不能满足你的需求,你也可以通过继承它来实现自己的类。这可以在/WEB-INF/web.xml中来具体指定。
要掌握ActionServlet,就必须了解它所扮演的角色。首先,ActionServlet表示MVC结构中的控制器部分,它需要完成控制器所需的前端控制及转发请求等职责。其次,ActionServlet被实现为一个专门处理HTTP请求的Servlet,它同时具有servlet的特点。在Struts 1.1中它主要完成以下功能:
- 接收客户端请求
- 根据客户端的URI将请求映射到一个相应的Action类
- 从请求中获取数据填充Form Bean(如果需要)
- 调用Action类的execute()方法获取数据或者执行业务逻辑
- 选择正确的视图响应客户
此外,ActionServlet还负责初始化和清除应用配置信息的任务。ActionServlet的初始化工作在init方法中完成,它可以分为两个部分:初始化ActionServlet自身的一些信息以及每个模块的配置信息。前者主要通过initInternal、initOther和initServlet三个方法来完成。
我们可以在/WEB-INF/web.xml中指定具体的控制器以及初始参数,由于版本的变化以及Struts 1.1中模块概念的引进,一些初始参数被废弃或者移入到/WEB-INF/struts-config.xml中定义。下面列出所有被废弃的参数,相应地在web.xml文件中也不鼓励再使用。
- application
- bufferSize
- content
- debug
- factory
- formBean
- forward
- locale
- mapping
- maxFileSize
- multipartClass
- nocache
- null
- tempDir
ActionServlet根据不同的模块来初始化ModuleConfig类,并在其中以XXXconfig集合的方式保存该模块的各种配置信息,比如ActionConfig,FormBeanConfig等。
初始化工作完成之后,ActionServlet准备接收客户请求。针对每个请求,方法process(HttpServletRequest request, HttpServletResponse response)将被调用。该方法指定具体的模块,然后调用该模块的RequestProcessor的process方法。
protected void process(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { RequestUtils.selectModule(request, getServletContext()); getRequestProcessor(getModuleConfig(request)).process(request, response); } |
RequestProcessor包含了Struts控制器的所有处理逻辑,它调用不同的processXXX方法来完成不同的处理。下表列出其中几个主要的方法:
方法 | 功能 |
processPath | 获取客户端的请求路径 |
processMapping | 利用路径来获得相应的ActionMapping |
processActionForm | 初始化ActionForm(如果需要)并存入正确的scope中 |
processActionCreate | 初始化Action |
processActionPerform | 调用Action的execute方法 |
processForwardConfig | 处理Action返回的ActionForward |
|
|
对于ActionForm你可以从以下几个方面来理解它:
- ActionForm表示HTTP窗体中的数据,可以将其看作是模型和视图的中介,它负责保存视图中的数据供模型或者视图使用。Struts 1.1文档中把它比作HTTP和Action之间的防火墙,这体现了ActionForm具有的过滤保护的作用,只有通过ActionForm验证的数据才能够发送到Action处理。
- ActionForm是与一个或多个ActionConfig关联的JavaBean,在相应的action的execute方法被调用之前,ActionForm会自动利用请求参数来填充自己(初始化属性)。
- ActionForm是一个抽象类,你必须通过继承来实现自己的类。
ActionForm首先利用属性的getter和setter方法来实现初始化,初始化完毕后,ActionForm的validate方法被调用,你可以在其中来检查请求参数的正确性和有效性,并且可以将错误信息以ActionErrors的形式返回到输入窗体。否则,ActionForm将被作为参数传给action的execute方法以供使用。
ActionForm bean的生命周期可以设置为session(缺省)和request,当设置为session时,记得在reset方法中将所有的属性重新设置为初始值。
由于ActionForm对应于HTTP窗体,所以随着页面的增多,你的ActionForm将会急速增加。而且可能同一类型页面字段将会在不同的ActionForm中出现,并且在每个ActionForm中都存在相同的验证代码。为了解决这个问题,你可以为整个应用实现一个ActionForm或者至少一个模块对应于一个ActionForm。
但是,聚合的代价就是复用性很差,而且难维护。针对这个问题,在Struts 1.1中提出了DynaActionForm的概念。
DynaActionForm类
DynaActionForm的目的就是减少ActionForm的数目,利用它你不必创建一个个具体的ActionForm类,而是在配置文件中配置出所需的虚拟ActionForm。例如,在下表中通过指定<form-bean>的type为"org.apache.struts.action.DynaActionForm"来创建一个动态的ActionForm--loginForm。
<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相同,但是要注意一点。普通的ActionForm对象需要为每个属性提供getter和setter方法,以上面的例子而言,我们需要提供getUsername() 和 setUsername()方法取得和设置username属性,同样地有一对方法用于取得和设置password属性和actionClass属性。
如果使用DynaActionForm,它将属性保存在一个HashMap类对象中,同时提供相应的get(name) 和 set(name)方法,其中参数name是要访问的属性名。例如要访问DynaActionForm中username的值,可以采用类似的代码:
String username = (String)form.get("username"); |
由于值存放于一个HashMap对象,所以要记得对get()方法返回的Object对象做强制性类型转换。正是由于这点区别,如果你在Action中非常频繁地使用ActionForm对象,建议还是使用普通的ActionForm对象。
在Struts 1.1中,除了DynaActionForm以外,还提供了表单输入自动验证的功能,在包org.apache.struts.validator中提供了许多有用的类,其中最常见的就是DynaValidatorForm类。
DynaValidatorForm类
DynaValidatorForm是DynaActionForm的子类,它能够提供动态ActionForm和自动表单输入验证的功能。和使用DynaActionForm类似,你必须首先在配置文件中进行配置:
<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> |
同时要定义验证的插件:
<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分别表示验证定义和验证规则的内容(可以合并在一起),比如针对上例中的DynaValidatorForm,我们有如下验证定义(validator.xml):
<?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"/> <!-- code sample is too wide --> <arg2 key="${var:maxlength}" name="maxlength" resource="false"/> <!-- code sample is too wide --> <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"> <!-- code sample is too wide --> <arg0 key="prompt.password"/> <arg1 key="${var:minlength}" name="minlength" resource="false"/> <!-- code sample is too wide --> <arg2 key="${var:maxlength}" name="maxlength" resource="false"/> <!-- code sample is too wide --> <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> |
从上述定义中,我们可以看到对于字段username有三项验证:required, minlength, maxlength,意思是该字段不能为空,而且长度在3和16之间。而validator-rules.xml文件则可以采用Struts提供的缺省文件。注意在<form-bean>中定义的form是如何与validation.xml中的form关联起来的。最后,要启动自动验证功能,还需要将Action配置的validate属性设置为true。
<action path="/login" type="com.ncu.test.LoginAction" name="loginForm" scope="request" input="tile.userLogin"validate="true"> |
此时,Struts将根据xml配置文件中的定义来检验表单输入,并将不符合要求的错误信息输出到页面。但是你可能会想:这个功能虽然好,可是什么检验都跑到服务器端执行,效率方面和用户易用性方面是不是有些问题?你可能会怀念起那简单的JavaScript客户端验证。
不用担心,在Struts 1.1中也支持JavaScript客户端验证。如果你选择了客户端验证,当某个表单被提交以后,Struts 1.1启动客户端验证,如果浏览器不支持JavaScript验证,则服务器端验证被启动,这种双重验证机制能够最大限度地满足各种开发者的需要。JavaScript验证代码也是在validator-rules.xml文件中定义的。要启动客户端验证,你必须在相应的JSP文件中做如下设置:
- 为<html:form>增加onsubmit属性
- 设置Javascript支持
下表中列出了一JSP文件的示例代码,红字部分为Javascript验证所需代码。
<%@ 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);"> <!-- code sample is too wide --> <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> <!-- code sample is too wide --> </table> </center> </html:form> <html:javascript formName="loginForm" dynamicJavascript="true" staticJavascript="false"/> <!-- code sample is too wide --> <script language="Javascript1.1" src="staticJavascript.jsp"></script> </td> </tr> </table> </td> </tr> </table> |
其中onsubmit的值为"return validateLoginForm(this);",它的语法为:
return validate + struts-config.xml中定义的form-bean名称 + (this);
staticJavascript.jsp的内容为:
<%@ page language="java" %> <%-- set document type to Javascript (addresses a bug in Netscape according to a web resource --%> <!-- code sample is too wide --><%@ page contentType="application/x-javascript" %> <%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %> <html:javascript dynamicJavascript="false" staticJavascript="true"/> |
如果validator-rules.xml中定义的基本验证功能不能满足你的需求,你可以自己添加所需的验证类型。
|
|
我们通过继承Action类来实现具体的执行类。具体Action类的功能一般都在execute(以前是perform方法)方法中完成,其中主要涉及到以下几个方面:
- 辅助ActionForm进行一些表单数据的检查。
- 执行必要的业务逻辑,比如存取数据库,调用实体bean等。
- 更新服务器端的bean数据,后续对象中可能会用到这些数据,比如在JSP中利用bean:write来获得这些数据。
- 根据处理结果决定程序的去处,并以ActionForward对象的形式返回给ActionServlet。
提示:由于在Action和ActionForm中都可以实现验证方法,那么如何来安排它们之间的分工呢?一般来说,我们秉着MVC分离的原则,也就是视图级的验证工作放在ActionForm来完成,比如输入不能为空,email格式是否正确,利用ValidatorForm可以很轻松地完成这些工作。而与具体业务相关的验证则放入Action中,这样就可以获得最大ActionForm重用性的可能。
前面我们提到过,我们主张将业务逻辑执行分离到单独的JavaBean中,而Action只负责错误处理和流程控制。而且考虑到重用性的原因,在执行业务逻辑的JavaBean中不要引用任何与Web应用相关的对象,比如HttpServletRequest,HttpServletResponse等对象,而应该将其转化为普通的Java对象。关于这一点,可以参考Petstore中WAF框架的实现思路。
此外,你可能还注意到execute与perform的一个区别:execute方法简单地掷出Exception异常,而perform方法则掷出ServletException和IOException异常。这不是说Struts 1.1在异常处理功能方面弱化了,而是为了配合Struts 1.1中一个很好的功能--宣称式异常处理机制。
|
|
和EJB中的宣称式事务处理概念类似,宣称式异常处理其实就是可配置的异常处理,你可以在配置文件中指定由谁来处理Action类中掷出的某种异常。你可以按照以下步骤来完成该功能:
- 实现org.apache.struts.action.ExceptionHandler的子类,覆盖execute方法,在该方法中处理异常并且返回一个ActionForward对象
- 在配置文件中配置异常处理对象,你可以配置一个全局的处理类或者单独为每个Action配置处理类
下表就定义了一个全局的处理类CustomizedExceptionHandler,它被用来处理所有的异常。
<global-exceptions> <exception handler="com.yourcorp.CustomizedExceptionHandler" key="global.error.message" path="/error.jsp" scope="request" type="java.lang.Exception"/> </global-exceptions> |
其中具体的参数含义,可以参考ExceptionHandler.java源文件。
|
|
讲完了模型和控制器,接下来我们要涉及的是视图。视图的角色主要是由JSP来完成,从JSP的规范中可以看出,在视图层可以"折腾"的技术不是很多,主要的就是自定义标记库的应用。Struts 1.1在原有的四个标记库的基础上新增了两个标记库--Tiles和Nested。
其中Tiles除了替代Template的基本模板功能外,还增加了布局定义、虚拟页面定义和动态页面生成等功能。Tiles强大的模板功能能够使页面获得最大的重用性和灵活性,此外可以结合Tiles配置文件中的页面定义和Action的转发逻辑,即你可以将一个Action转发到一个在Tiles配置文件中定义的虚拟页面,从而减少页面的数量。比如,下表中的Action定义了一个转发路径,它的终点是tile.userMain,而后者是你在Tiles配置文件中定义的一个页面。
<!-- ========== 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配置文件:tiles-defs.xml
<!DOCTYPE tiles-definitions PUBLIC "-//Apache Software Foundation//DTD Tiles Configuration//EN" "http://jakarta.apache.org/struts/dtds/tiles-config.dtd"> <!-- code sample is too wide --><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标记库的作用是让以上这些基本标记库能够嵌套使用,发挥更大的作用。
|
|
所谓的Commons Logging接口,是指将日志功能的使用与日志具体实现分开,通过配置文件来指定具体使用的日志实现。这样你就可以在Struts 1.1中通过统一的接口来使用日志功能,而不去管具体是利用的哪种日志实现,有点于类似JDBC的功能。Struts 1.1中支持的日志实现包括:Log4J,JDK Logging API, LogKit,NoOpLog和SimpleLog。
你可以按照如下的方式来使用Commons Logging接口(可以参照Struts源文中的许多类实现):
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文件:
# Note: The Tiles framework now uses the commons-logging package to output different information or debug statements. <!-- code sample is too wide -->Please refer to this package documentation to enable it. The simplest way to enable logging is to create two files in <!-- code sample is too wide -->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文件:
# Logging detail level, # Must be one of ("trace", "debug", "info", "warn", "error", or "fatal"). org.apache.commons.logging.simplelog.defaultlog=fatal |
这里我们采用的日志实现是SimpleLog,你可以在simplelog.properties文件指定日志明细的级别:trace,debug,info,warn,error和fatal,从trace到fatal错误级别越来越高,同时输出的日志信息也越来越少。而这些级别是和org.apache.commons.logging.log接口中的方法一一对应的。这些级别是向后包含的,也就是前面的级别包含后面级别的信息。
发表评论
-
在struts中使用checkbox实现批量删除
2010-04-01 20:39 1662在struts中使用checkbox实现批量删除 JSP ... -
Hibernate分页
2009-11-13 13:24 1000在进行web应用开发的时候经常要进行分页处 ... -
Hibernate主键生成方式
2009-09-20 13:05 7631) assigned 主键由外部程序负责生成,无需Hibe ... -
结合Struts和Hibernate谈J2EE架构的数据表示
2009-09-17 00:36 768在 struts+ hibernate 这种结构中,是不应该把 ... -
DispatchAction的详细说明
2009-09-09 00:03 1267DispatchAction, LookupDi ... -
Struts标签库详解(三)
2009-09-08 14:31 1022Bean 标签库 此标签库和Java Bean ... -
Struts标签库详解(二)
2009-09-08 14:30 981<form>标签系列使用& ... -
Struts标签库详解(一)
2009-09-08 14:29 948Struts提供了五个标签库,即:HTML、Bean、Log ... -
胡诌Spring
2009-09-05 22:50 1129像Struts一样, ... -
两个字母搞定J2EE通用分页标签(二)
2009-08-24 10:21 1047作者:张纪豪(转载请注明出处) (三)、数据访问层设计与数据 ... -
两个字母搞定J2EE通用分页标签(三)
2009-08-24 10:23 1074作者:张纪豪(转载请注明出处) (四)、控制层取得分页数据 ... -
两个字母搞定J2EE通用分页标签(四)
2009-08-24 10:26 1023作者:张纪豪(转载请注明出处) (五)、视图层的JSP页面输 ... -
两个字母搞定J2EE通用分页标签(一):
2009-09-01 18:16 901作者:张纪豪(转载请注明出处) (一)摘要与设计思想 ... -
ApplicationResources
2009-08-04 16:02 786能够为ActionServlet同时指定多个xml配置文件, ... -
修改action
2009-08-05 12:24 812更改源文件MyAction.java package str ... -
myeclipse中如何自动生成hibernate得POJO和hbm.xml文件
2009-08-14 21:21 4593在Eclipse中打开MyEclipse的DbBrowser窗 ...
相关推荐
Struts1.x与Struts2.x是两种非常流行的Java Web应用程序框架,它们都由Apache软件基金会开发,旨在简化MVC(Model-View-Controller)架构的实现。然而,两者在设计哲学、功能特性以及实现方式上存在显著差异。以下是...
### Struts 1.x 总结 #### 一、Struts 框架概述 Struts 是一个基于 Java 的开源框架,它实现了 Model-View-Controller (MVC) 设计模式,帮助开发者构建可扩展、易于维护的 Web 应用程序。在 Struts 1.x 版本中,其...
Struts1.x 和 Hibernate 是两种在Java Web开发中广泛使用的开源框架,它们分别负责不同的职责。Struts1.x 是一个MVC(Model-View-Controller)框架,主要用于处理Web应用程序的业务逻辑和用户交互,而Hibernate则是...
总结,Struts1.x作为经典的Web开发框架,其丰富的功能和广泛的应用使得学习和掌握它成为提升Java Web开发技能的重要一步。通过本教程,你将对Struts1.x有深入的理解,并能将其应用于实际项目中,构建出高效、稳定的...
总结来说,Struts1.x 提供了一个结构化的Web应用开发框架,通过配置文件管理请求处理流程,使得开发者能够更专注于业务逻辑,而不是底层的HTTP请求处理。虽然现在Struts1.x 已经被更新的框架如Spring MVC所替代,但...
### Struts1.x 入门知识点详解 #### 一、Struts 概念与起源 Struts 是一款基于 Java 的开源 MVC(Model-View-Controller)框架,最初由 Apache Jakarta 项目开发。其目的是简化 Web 应用程序的开发过程,并提供一...
总结来说,Struts2在保留Struts1.x核心优势的基础上,通过引入拦截器、类型转换、AJAX支持等新特性,提升了开发效率,降低了维护成本,从而成为了更好的Web开发框架选择。虽然Struts1.x仍有一定的用户基础,但Struts...
总结,Struts1.x的验证框架为Java Web开发者提供了一套方便的数据验证机制,能够有效提升应用的安全性和用户体验。虽然在现代开发中,Struts1.x已经逐渐被Spring MVC等更现代的框架取代,但了解和理解其验证框架仍然...
总结起来,Struts2在设计模式、配置方式、数据绑定、异常处理、视图渲染、插件体系、国际化、测试友好和性能等方面都对Struts1.x进行了显著的改进。这些改进使得Struts2更适合现代Web开发的需求,也更便于团队协作和...
总结,Struts1.x作为早期流行的Java Web框架,它的设计思想和实现方式对后来的框架有着深远影响。虽然现在已经有了更先进的替代品,如Spring MVC,但理解Struts1.x的基本原理和使用方法,对于理解Web开发的演变历史...
总结来说,这个集成例子展示了如何利用Struts1.x处理用户请求,Spring管理业务逻辑和事务,以及JTA处理跨资源的事务一致性。通过学习和实践这个例子,开发者可以深入理解这三大技术的协同工作,为构建健壮、可扩展的...
总结来说,Struts1.x的异常处理机制包括全局异常配置和自定义Action异常处理两部分。通过合理利用这两种方式,开发者可以有效地控制和管理应用程序的异常,提供更健壮的错误处理,提高系统的稳定性和用户体验。在...
总结来说,基于Struts1.x的验证码实现是Web开发中的重要环节,它涉及到服务器端的生成、存储、验证,以及客户端的显示和用户交互。通过合理的验证码设计和实现,可以显著提高Web应用程序的安全性,保护用户的账户不...
这个"j2ee学习struts2.x总结1"的主题着重于初学者如何理解和掌握Struts2的基础知识,以及如何进行环境搭建。下面将详细讨论相关知识点。 1. **Struts2简介**: Struts2是Apache软件基金会的一个项目,它是Struts1...
总结来说,这个集成示例提供了一个完整的Java Web开发环境,展示了如何利用Struts1.x进行控制层操作,Spring进行业务层管理,Hibernate进行数据持久化,以及Ehcache进行性能优化。通过学习和实践这个例子,开发者...
### Struts1.x 标签详解 #### 一、引言 Struts 是 Apache Jakarta 的一个著名开源项目,旨在为构建基于 Java 的 Web 应用程序提供一个强大的框架。Struts 提供了大量的标签来帮助开发者简化开发过程。本文将详细...
总结来说,Spring MVC和Struts2.x各有优势,选择哪一个取决于项目需求、团队技术栈以及个人偏好。Spring MVC在灵活性、可扩展性和现代开发趋势方面表现出色,而Struts2.x则以其稳定性和成熟的社区支持赢得了一部分...
Struts是Java Web开发中的一个流行框架,分为Struts 1.x和Struts 2.0两个主要版本。这两个版本虽然都旨在简化MVC(模型-视图-控制器)架构的实现,但在设计和功能上有着显著的区别。下面将详细介绍这两个版本的核心...
Struts框架是Java Web开发中的一个经典框架,由Apache软件基金会维护,主要用于构建基于MVC...然而,由于Struts 1.x存在一些设计上的局限性,如性能问题和代码耦合度高等,现在许多项目倾向于选择更新、更灵活的框架。