jsp框架之Struts1.x學習簡單總結打賞

Struts是基于Model 2之上的,而Model 2是經典的MVC(模型-視圖-控制器)模型的Web應用變體,這個改變主要是由于網絡應用的特性--HTTP協議的無狀態性引起的。Model 2的目的和MVC一樣,也是利用控制器來分離模型和視圖,達到一種層間松散耦合的效果,提高系統靈活性、復用性和可維護性。在多數情況下,你可以將Model 2與MVC等同起來。 在利用Model 2之前,我們是把所有的表示邏輯和業務邏輯都集中在一起(比如大雜燴似的JSP),有時也稱這種應用模式為Model 1,Model 1的主要缺點就是緊耦合,復用性差以及維護成本高。

Struts 1.1 和Model 2

既然Struts 1.1是基于Model 2之上,那它的底層機制也就是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中,為了解決這個并行開發的問題,提出了兩種解決方案:

  1. 多個配置文件的支持
  2. 模塊的支持

支持多個配置文件,是指你能夠為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>

為了徹底解決這種沖突,Struts 1.1中引進了模塊(Module)的概念。一個模塊就是一個獨立的子系統,你可以在其中進行任意所需的配置,同時又不必擔心和其它的配置文件產生沖突。因為前面我們講過,ActionServlet是將不同的模塊信息保存在不同的ModuleConfig對象中的。要使用模塊的功能,需要進行以下的準備工作:這種方法可以很好地解決修改沖突的問題,不同的開發人員可以在不同的配置文件中設置自己的Action、ActionForm等等(當然不是說每個開發人員都需要自己的配置文件,可以按照系統的功能模塊進行劃分)。但是,這里還是存在一個潛在的問題,就是可能不同的配置文件之間會產生沖突,因為在ActionServlet初始化的時候這幾個文件最終還是需要合并到一起的。比如,在struts-config.xml中配置了一個名為success的<forward>,而在struts-config-registration.xml中也配置了一個同樣的<forward>,那么執行起來就會產生沖突。 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>

3、準備各個模塊所需的ActionForm、Action和JSP等資源要配置多個模塊,你需要在原有的一個<init-param>(在Struts 1.1中將其對應的模塊稱為缺省模塊)的基礎之上,增加模塊對應的<init-param>。其中<param-name>表示為config/XXX的形式,其中XXX為對應的模塊名,<param-value>中還是指定模塊對應的配置文件。上面這個例子說明該應用有三個模塊,分別是缺省模塊、customer和order,它們分別對應不同的配置文件。 但是要注意的是,模塊的出現也同時帶來了一個問題,即如何在不同模塊間進行轉發?有兩種方法可以實現模塊間的轉發,一種就是在<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>
...

ActionServlet

我們首先來了解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你可以從以下幾個方面來理解它:

  1. ActionForm表示HTTP窗體中的數據,可以將其看作是模型和視圖的中介,它負責保存視圖中的數據供模型或者視圖使用。Struts 1.1文檔中把它比作HTTP和Action之間的防火墻,這體現了ActionForm具有的過濾保護的作用,只有通過ActionForm驗證的數據才能夠發送到Action處理。
  2. ActionForm是與一個或多個ActionConfig關聯的JavaBean,在相應的action的execute方法被調用之前,ActionForm會自動利用請求參數來填充自己(初始化屬性)。
  3. 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>

如果使用DynaActionForm,它將屬性保存在一個HashMap類對象中,同時提供相應的get(name) 和 set(name)方法,其中參數name是要訪問的屬性名。例如要訪問DynaActionForm中username的值,可以采用類似的代碼:動態的ActionForm的使用方法跟普通的ActionForm相同,但是要注意一點。普通的ActionForm對象需要為每個屬性提供getter和setter方法,以上面的例子而言,我們需要提供getUsername() 和 setUsername()方法取得和設置username屬性,同樣地有一對方法用于取得和設置password屬性和actionClass屬性。

String username = (String)form.get("username");

在Struts 1.1中,除了DynaActionForm以外,還提供了表單輸入自動驗證的功能,在包org.apache.struts.validator中提供了許多有用的類,其中最常見的就是DynaValidatorForm類。由于值存放于一個HashMap對象,所以要記得對get()方法返回的Object對象做強制性類型轉換。正是由于這點區別,如果你在Action中非常頻繁地使用ActionForm對象,建議還是使用普通的ActionForm對象。

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>

同時要定義驗證的插件: 其中的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>
<action path="/login"
type="com.ncu.test.LoginAction"
name="loginForm"
scope="request"
input="tile.userLogin"validate="true">

從上述定義中,我們可以看到對于字段username有三項驗證:required, minlength, maxlength,意思是該字段不能為空,而且長度在3和16之間。而validator-rules.xml文件則可以采用Struts提供的缺省文件。注意在<form-bean>中定義的form是如何與validation.xml中的form關聯起來的。最后,要啟動自動驗證功能,還需要將Action配置的validate屬性設置為true。 此時,Struts將根據xml配置文件中的定義來檢驗表單輸入,并將不符合要求的錯誤信息輸出到頁面。但是你可能會想:這個功能雖然好,可是什么檢驗都跑到服務器端執行,效率方面和用戶易用性方面是不是有些問題?你可能會懷念起那簡單的JavaScript客戶端驗證。 不用擔心,在Struts 1.1中也支持JavaScript客戶端驗證。如果你選擇了客戶端驗證,當某個表單被提交以后,Struts 1.1啟動客戶端驗證,如果瀏覽器不支持JavaScript驗證,則服務器端驗證被啟動,這種雙重驗證機制能夠最大限度地滿足各種開發者的需要。JavaScript驗證代碼也是在validator-rules.xml文件中定義的。要啟動客戶端驗證,你必須在相應的JSP文件中做如下設置:

  1. 為<html:form>增加onsubmit屬性
  2. 設置Javascript支持

下表中列出了一JSP文件的示例代碼,紅字部分為Javascript驗證所需代碼。 return validate + struts-config.xml中定義的form-bean名稱 + (this);其中onsubmit的值為"return validateLoginForm(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"/>

輔助ActionForm進行一些表單數據的檢查。如果validator-rules.xml中定義的基本驗證功能不能滿足你的需求,你可以自己添加所需的驗證類型。 Action 我們通過繼承Action類來實現具體的執行類。具體Action類的功能一般都在execute(以前是perform方法)方法中完成,其中主要涉及到以下幾個方面:

  1. 執行必要的業務邏輯,比如存取數據庫,調用實體bean等。
  2. 更新服務器端的bean數據,后續對象中可能會用到這些數據,比如在JSP中利用bean:write來獲得這些數據。
  3. 根據處理結果決定程序的去處,并以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類中擲出的某種異常。你可以按照以下步驟來完成該功能:

  1. 實現org.apache.struts.action.ExceptionHandler的子類,覆蓋execute方法,在該方法中處理異常并且返回一個ActionForward對象
  2. 在配置文件中配置異常處理對象,你可以配置一個全局的處理類或者單獨為每個Action配置處理類

下表就定義了一個全局的處理類CustomizedExceptionHandler,它被用來處理所有的異常。

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

taglib其中具體的參數含義,可以參考ExceptionHandler.java源文件。 其中Tiles除了替代Template的基本模板功能外,還增加了布局定義、虛擬頁面定義和動態頁面生成等功能。Tiles強大的模板功能能夠使頁面獲得最大的重用性和靈活性,此外可以結合Tiles配置文件中的頁面定義和Action的轉發邏輯,即你可以將一個Action轉發到一個在Tiles配置文件中定義的虛擬頁面,從而減少頁面的數量。比如,下表中的Action定義了一個轉發路徑,它的終點是tile.userMain,而后者是你在Tiles配置文件中定義的一個頁面。taglib 講完了模型和控制器,接下來我們要涉及的是視圖。視圖的角色主要是由JSP來完成,從JSP的規范中可以看出,在視圖層可以"折騰"的技術不是很多,主要的就是自定義標記庫的應用。Struts 1.1在原有的四個標記庫的基礎上新增了兩個標記庫--Tiles和Nested。

<!-- ========== 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>
<!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>

Tiles配置文件:tiles-defs.xml 而Nested標記庫的作用是讓以上這些基本標記庫能夠嵌套使用,發揮更大的作用。

Commons Logging 接口

所謂的Commons Logging接口,是指將日志功能的使用與日志具體實現分開,通過配置文件來指定具體使用的日志實現。這樣你就可以在Struts 1.1中通過統一的接口來使用日志功能,而不去管具體是利用的哪種日志實現,有點于類似JDBC的功能。Struts 1.1中支持的日志實現包括:Log4J,JDK Logging API, LogKit,NoOpLog和SimpleLog。 你可以按照如下的方式來使用Commons Logging接口(可以參照Struts源文中的許多類實現):

// ...
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;
}
// ...
}

commons-logging.properties文件:而開啟日志功能最簡單的辦法就是在WEB-INF/classes目錄下添加以下兩個文件:
# 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接口中的方法一一對應的。這些級別是向后包含的,也就是前面的級別包含后面級別的信息。

jsp框架之Struts1.x學習簡單總結
文章《jsp框架之Struts1.x學習簡單總結》二維碼
  • 微信打賞
  • 支付寶打賞

已有4條評論

  1. 冷庫

    不錯 加油

    2012-04-25 11:05 回復
  2. 游客 221

    期待博主更新文章…www.9886.org太原婦科醫院支持了!

    2012-04-20 15:46 回復
  3. 速騰 坐墊

    還不錯

    2012-04-20 12:52 回復
  4. 游客 756

    不錯 加油

    2012-04-18 23:14 回復

(必填)

(必填)

(可選)

黑龙江22选5开奖