struts1 Action原理與配置
今天臨時調到另外一個專案幫忙,三天時間修改一個功能,e(⊙o⊙)…,剛down下專案一看是struts1+Hibernate3,平時一直採用spring+springMvc+springData+Hibernate,之前只接觸過struts2還好久沒用了,只好先來看一下struts1的action配置了,又因為時間有限有限只好摘抄他人文章了,哈哈
首先介紹下struts1工作原理:
1.初始化:struts框架的總控制器ActionServlet是一個Servlet,它在web.xml中配置成自動啟動的
Servlet,在啟動時總控制器會讀取配置檔案(struts-config.xml)的配置資訊,為struts
中不同的模組初始化相應的物件。(面向物件思想)
2.傳送請求:使用者提交表單或通過URL向WEB伺服器提交請求,請求的資料用HTTP協議傳給web伺服器。
3.form填充:struts的總控制器ActionServlet在使用者提交請求時將資料放到對應的form物件中的成員
變數中。
4.派發請求:控制器根據配置資訊物件ActionConfig將請求派發到具體的Action,對應的formBean一併
傳給這個Action中的excute()方法。
5.處理業務:Action一般只包含一個excute()方法,它負責執行相應的業務邏輯(呼叫其它的業務模組)
完畢後返回一個ActionForward物件。伺服器通過ActionForward物件進行轉發工作。
6.返回響應:Action將業務處理的不同結果返回一個目標響應物件給總控制器。
7.查詢響應:總控制器根據Action處理業務返回的目標響應物件,找到對應的資源物件,一般情況下
為jsp頁面。
8.響應使用者:目標響應物件將結果傳遞給資源物件,將結果展現給使用者。
下面具體介紹一下struts1配置並配合簡單的例子簡單易懂:
Action, ActionForm, ActionForward ,這三個物件構成了Struts 的核心。
Struts 最核心的控制器是ActionServlet ,該Servlet 攔截使用者請求,井將使用者請求轉入到Struts 體系內。
一、配置ActionServlet
ActionServlet 是一個標準的Servlet ,在web.xml 檔案中配置,該Servlet 用於攔所有的HTTP 請求。
在web.xml 檔案中配置ActionServlet 應增加如下片段:
<servlet>
<!-- ActionServlet 的名 -->
<servlet-name>actionSevlet</servlet-name>
<!-- 配置Servlet 的實現類 -->
<servlet-class>
org.apache.struts.action.ActionServlet
</servlet-class>
<!-- 指定Struts 的第一個配置檔案 -->
<init-param>
<!-- 指定配置檔案的對映 -->
<param-name>config</param-name>
<param-value>/WEB-INF/struts-con工fgl.xml</param-value>
</init-param>
<!-- 指定Struts 的第二個配置檔案 -->
<init-param>
<!-- 指定配置檔案的對映 -->
<param-name>config/wawa</param-name>
<param-value>/WEB-INF/struts-config2.xml</param-value>
</init-param>
<!-- 將ActionServlet配置成自啟動Servlet -->
<load-on-startup>2</load-on-startup>
</servlet>
二、配置ActionForm
配置ActionForm ,必須包含ActionForm 類才行。Struts 要求ActionForm 必須繼承Struts 的基類: org.apache.struts.action.ActionForm,ActionForm 的實現非常簡單,該類只是一個普通的JavaBean,只要為每個屬性提供對應的setter 和getter 方法即可。根據前面的講解, ActionForm
用於封裝使用者的請求引數,而請求引數是通過JSP 頁面的表單域傳遞過來的。因此應保證ActionForm 的引數與表單域的名字相同。
注意: JavaB ean 的引數是根據getter 、setter 方法確定的。如果希望有一個A 的屬性,則應該提供getA 和setA 的方法。
(1)ActionForm的實現
ActionForm 的屬性必須與JSP 頁面的表單域相同。本示例的表單包含如下兩個表單域:
• usemame
• password
因此, ActionForm 必須繼承org.apache.struts.action.ActionForm,併為這兩個域提供對應的setter 和getter 方法,下面是ActionForm 的原始碼:
import org.apache.struts.action.ActionForm;
public class LoginForm extends ActionForm {
private String username;
private String password;
// 表單域username對應的setter 方法
/**
* @return the username
*/
public String getUsername() {
return username;
}
/**
* @param username
* the username to set
*/
public void setUsername(String username) {
this.username = username;
}
/**
* @return the password
*/
public String getPassword() {
return password;
}
/**
* @param password
* the password to set
*/
public void setPassword(String password) {
this.password = password;
}
}
(2)ActionForm 的配置
所有的ActionForm 都被配置在struts-config.xml 檔案中,該檔案包括了一個form-beans 的元素,該元素內定義了所有的ActionForm,每個ActionForm 對應一個form-bean 元素。
為了定義LoginForm. 必須在struts-config.xml檔案中增加如下程式碼:
<!-- 用於定義所有的ActionForm -->
<form-beans>
<!-- 定義ActionForm,至少指定兩個屬性: name , type-->
<form-bean name="loginForm" type="lee.LoginForm" />
</form-beans>
三、配置Action
Action 的配置比ActionForm 相對複雜一點,因為Action 負責管理與之關聯的ActionForm. 它不僅需要配置實現類,還需要配置Action 的path 屬性,該屬性用於被用
戶請求。對於只需在本Action 內有效的Forward. 還應在Action 元素內配置區域性Forward。
(1)Action 的實現
通過ActionForm. 可使Action 無須從HTTP 請求中解析引數。因為所有的引數都被封裝在ActionForm中,下面是Action 從AcitionForm 取得請求引數的原始碼:
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
public class LoginAction extends Action {
// 必須重寫該核心方法,該方法actionForm 將表單的請求引數封裝成值物件
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
//將ActionForm強制型別轉換為LoginForm
LoginForm loginForm = (LoginForm) form;
// 從ActionForm中解析出請求引數: username
String username = loginForm.getUsername();
// 從ActionForm中解析出請求引數: password
String pass = loginForm.getUsername();
//後面的處理與前一個示例的Action 相同。
...
}
}
該Action 從轉發過來的ActionForm 中解析請求引數,對應的ActionForm 則由ActionServlet 在接收到使用者請求時,負責例項化。
實際的過程是: ActionServlet 攔截到使用者請求後,根據使用者的請求,在配置檔案中查詢對應的Action , Action 的name 屬性指定了用於封裝請求引數的ActionForm; 然後ActionServlet 將建立預設的ActionForm 例項,並呼叫對應的setter 方法完成ActionForm的初始化。
ActionServlet 在分發使用者請求時,也將對應ActionForm 的例項一同分發過來。
(2)Action 的配置
Action 需要配置如下幾個方面。
• Action 的path: ActionServlet 根據該屬性來轉發使用者的請求,即將使用者請求轉發與之同名的Action 。同名的意思是:將請求的.do 字尾去掉,匹配Action 的path屬性值。
• Action 的name: 此處的name 屬性並不是Action 本身的名字,而是與Action 關聯的ActionForm。因此該name 屬性必須是前面存在的ActionForm 名。
• Action 的type: 該屬性用於指定Action 的實現類,也就是負責處理使用者請求的業
務控制器。
• 區域性Forward: Action 的轉發並沒有轉發到實際的JSP 資源,而是轉發到邏輯名,即Forward 名。在Action 內配置的Forward 都是區域性Forward (該Forward 只在該Action 內有效)。
下面是該Action 的配置程式碼:
<!-- 該元素裡配置所有的Action -->
<action-mappings>
<!-- 配置Action. 指定了path , name , type 等屬性 -->
<action path="/login" type="lee.LoginAction" name="loginForm">
<!-- 配置區域性Forward -->
<forward name="welcome" path="/WEB-INF/jsp/welcome.jsp" />
<forward name="input" path="/login.jsp" />
</action>
</action-mappings>
四、配置Forward
正如前面所講, Forward 分區域性Forward 和全域性Forward 兩種。前者在Action 裡配置,僅對該Action 有效:後者單獨配置,對所有的Action 都有效。
配置Forward 非常簡單,主要需要指定以下三個屬性。
• name: 該Forward 的邏輯名。
• path: 該Forward 對映到的JSP 資源。
• redirect: 是否使用重定向。
區域性Forward 作為Action 的子元素配置;全域性Forward 配置在global-forwards 元素裡。
下面是配置全域性Forward 的程式碼:
<!-- 配置全域性Forward -->
<global-forwards>
<!-- 配置Forward物件的name 和path 屬性 -->
<forward name="error" path="/WEB-INF/jsp/error.jsp" />
</global-forwards>
上面的配置程式碼中,配置了一個全域性Forward,該Forward 可以被所有的Action 訪問。通常,只將全域性資源配置成全域性Forward。當每個Action 在轉發時,首先在區域性Forward 中查詢與之對應的Forward,如果在區域性Forward 中找不到對應的Forward 物件,才會到全域性Forward 中查詢。因此,區域性Forward 可以覆蓋全域性Forward。
下面提供了該應用的struts-config.xm1檔案的全部原始碼:
<?xml version="1.0" encoding="UTF-8"?>
<!-- Struts 配置檔案的檔案頭,包含DTD 等資訊 -->
<!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.2//EN" "http://struts.apache.org/dtds/struts-config_1_2.dtd">
<!--Struts 配置檔案的根元素 -->
<struts-config>
<!--配置所有的ActionForm -->
<form-beans>
<!--配置第一個ActionForm,指定ActionForm的name 和type 屬性 -->
<form-bean name="loginForm" type="lee.LoginForm" />
</form-beans>
<!--配置全域性Forward物件 -->
<global-forwards>
<!--該Forward物件的name 屬性為error. 對映資源為/WEB-INF/jsp/error.jsp -->
<forward name="error" path="/WEB-INF/jsp/error.jsp" />
</global-forwards>
<!--此處配置所有的Action 對映-->
<action-mappings>
<!--配置Action 的path. type 屬性name 屬性配置Action 對應的ActionForm-->
<action path="/login" type="lee.LoginAction" name="loginForm">
<!--還配置了兩個區域性Forward. 這兩個區域性Forward僅對該Action有效-->
<forward name="welcome" path="/WEB-INF/jsp/welcome.jsp" />
<forward name="input" path="/login.jsp" />
</action>
</action-mappings>
</struts-config>
配置檔案詳解如下:
<?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.dtd">
<!-- struts-config.xml中的元素必須按照上述doc指令中的dtd文件定義順序書寫,本例即遵從了dtd定義順序 -->
<!-- struts-config是整個xml的根元素,其他元素必須被包含其內 -->
<struts-config>
<!--
名稱:data-sources
描述:data-sources元素定義了web App所需要使用的資料來源
數量:最多一個
子元素:data-source
-->
<data-sources>
<!--
名稱:data-source
描述:data-source元素定義了具體的資料來源
數量:任意多個
屬性:
@key:當需要配置多個數據源時,相當於資料來源的名稱,用來資料來源彼此間進行區別
@type:可以使用的資料來源實現的類,一般來自如下四個庫
Poolman,開放原始碼軟體
Expresso,Jcorporate
JDBC Pool,開放原始碼軟體
DBCP,Jakarta
-->
<data-source key="firstOne" type="org.apache.commons.dbcp.BasicDataSource">
<!--
名稱:set-property
描述:用來設定資料來源的屬性
屬性:
@autoCommit:是否自動提交 可選值:true/false
@description:資料來源描述
@driverClass:資料來源使用的類
@maxCount:最大資料來源連線數
@minCount:最小資料來源連線數
@user:資料庫使用者
@password:資料庫密碼
@url:資料庫url
-->
<set-property property="autoCommit" value="true"/>
<set-property property="description" value="Hello!"/>
<set-property property="driverClass" value="com.mysql.jdbc.Driver"/>
<set-property property="maxCount" value="10"/>
<set-property property="minCount" value="2"/>
<set-property property="user" value="root"/>
<set-property property="password" value=""/>
<set-property property="url" value="jdbc:mysql://localhost:3306/helloAdmin"/>
</data-source>
</data-sources>
<!--
名稱:form-beans
描述:用來配置多個ActionForm Bean
數量:最多一個
子元素:form-bean
-->
<form-beans>
<!--
名稱:form-bean
描述:用來配置ActionForm Bean
數量:任意多個
子元素:form-property
屬性:
@className:指定與form-bean元素相對應的配置類,一般預設使用org.apaceh.struts.config.FormBeanConfig,如果自定義,則必須繼承 FormBeanConfig
@name:必備屬性!為當前form-bean制定一個全域性唯一的識別符號,使得在整個Struts框架內,可以通過該識別符號來引用這個ActionForm Bean。
@type:必備屬性!指明實現當前ActionForm Bean的完整類名。
-->
<form-bean name="Hello" type="myPack.Hello">
<!--
名稱:form-property
描述:用來設定ActionForm Bean的屬性
數量:根據實際需求而定,例如,ActionForm Bean對應的一個登陸Form中有兩個文字框,name和password,ActionForm Bean中也有這兩個欄位,則此處編寫兩個form-property來設定屬性
屬性:
@className:指定與form-property相對應的配置類,預設是org.apache.struts.config.FormPropertyConfig,如果自定義,則必須繼承FormPropertyConfig類
@name:所要設定的ActionForm Bean的屬性名稱
@type:所要設定的ActionForm Bean的屬性值的類
@initial:當前屬性的初值
-->
<form-property name="name" type="java.lang.String"/>
<form-property name="number" type="java.lang.Iteger" initial="18"/>
</form-bean>
</form-beans>
<!--
名稱:global-exceptions
描述:處理異常
數量:最多一個
子元素:exception
-->
<global-exceptions>
<!--
名稱:exception
描述:具體定義一個異常及其處理
數量:任意多個
屬性:
@className:指定對應exception的配置類,預設為org.apache.struts.config.ExceptionConfig
@handler:指定異常處理類,預設為org.apache.struts.action.ExceptionHandler
@key:指定在Resource Bundle種描述該異常的訊息key
@path:指定當發生異常時,進行轉發的路徑
@scope:指定ActionMessage例項存放的範圍,預設為request,另外一個可選值是session
@type:必須要有!指定所需要處理異常類的名字。
@bundle:指定資源繫結
-->
<exception
key=""hello.error
path="/error.jsp"
scope="session"
type="hello.HandleError"/>
</global-exceptions>
<!--
名稱:global-forwards
描述:定義全域性轉發
數量:最多一個
子元素:forward
-->
<global-forwards>
<!--
名稱:forward
描述:定義一個具體的轉發
數量:任意多個
屬性:
@className:指定和forward元素對應的配置類,預設為org.apache.struts.action.ActionForward
@contextRelative:如果為true,則指明使用當前上下文,路徑以“/”開頭,預設為false
@name:必須配有!指明轉發路徑的唯一識別符號
@path:必須配有!指明轉發或者重定向的URI。必須以"/"開頭。具體配置要與contextRelative相應。
@redirect:為true時,執行重定向操作,否則執行請求轉發。預設為false
-->
<forward name="A" path="/a.jsp"/>
<forward name="B" path="/hello/b.do"/>
</global-forwards>
<!--
名稱:action-mappings
描述:定義action集合
數量:最多一個
子元素:action
-->
<action-mappings>
<!--
名稱:action
描述:定義了從特定的請求路徑到相應的Action類的對映
數量:任意多個
子元素:exception,forward(二者均為區域性量)
屬性:
@attribute:制定與當前Action相關聯的ActionForm Bean在request和session範圍內的名稱(key)
@className:與Action元素對應的配置類。預設為org.apache.struts.action.ActionMapping
@forward:指名轉發的URL路徑
@include:指名包含的URL路徑
@input:指名包含輸入表單的URL路徑,表單驗證失敗時,請求會被轉發到該URL中
@name:指定和當前Acion關聯的ActionForm Bean的名字。該名稱必須在form-bean元素中定義過。
@path:指定訪問Action的路徑,以"/"開頭,沒有副檔名
@parameter:為當前的Action配置引數,可以在Action的execute()方法中,通過呼叫ActionMapping的getParameter()方法來獲取引數
@roles:指定允許呼叫該Aciton的安全形色。多個角色之間用逗號分割。處理請求時,RequestProcessor會根據該配置項來決定使用者是否有呼叫該Action的許可權
@scope:指定ActionForm Bean的存在範圍,可選值為request和session。預設為session
@type:指定Action類的完整類名
@unknown:值為true時,表示可以處理使用者發出的所有無效的Action URL。預設為false
@validate:指定是否要先呼叫ActionForm Bean的validate()方法。預設為true
注意:如上屬性中,forward/include/type三者相斥,即三者在同一Action配置中只能存在一個。
-->
<action path="/search"
type="addressbook.actions.SearchAction"
name="searchForm"
scope="request"
validate="true"
input="/search.jsp">
<forward name="success" path="/display.jsp"/>
</action>
</action-mappings>
<!--
名稱:controller
描述:用於配置ActionServlet
數量:最多一個
屬性:
@bufferSize:指定上傳檔案的輸入緩衝的大小.預設為4096
@className:指定當前控制器的配置類.預設為org.apache.struts.config.ControllerConfig
@contentType:指定相應結果的內容型別和字元編碼
@locale:指定是否把Locale物件儲存到當前使用者的session中,預設為false
@processorClass:指定負責處理請求的Java類的完整類名.預設org.apache.struts.action.RequestProcessor
@tempDir:指定檔案上傳時的臨時工作目錄.如果沒有設定,將才用Servlet容器為web應用分配的臨時工作目錄.
@nochache:true時,在相應結果中加入特定的頭引數:Pragma ,Cache-Control,Expires防止頁面被儲存在可數瀏覽器的快取中,預設為false
-->
<controller
contentType="text/html;charset=UTF-8"
locale="true"
processorClass="CustomRequestProcessor">
</controller>
<!--
名稱:message-resources
描述:配置Resource Bundle.
數量:任意多個
屬性:
@className:指定和message-resources對應的配置類.預設為org.apache.struts.config.MessageResourcesConfig
@factory:指定資源的工廠類,預設為org.apache.struts.util.PropertyMessageResourcesFactory
@key:
@null:
@parameter:
-->
<message-resources
null="false"
parameter="defaultResource"/>
<message-resources
key="images"
null="false"
parameter="ImageResources"/>
<!--
名稱:plug-in
描述:用於配置Struts的外掛
數量:任意多個
子元素:set-property
屬性:
@className:指定Struts外掛類.此類必須實現org.apache.struts.action.PlugIn介面
-->
<plug-in
className="org.apache.struts.validator.ValidatorPlugIn">
<!--
名稱:set-property
描述:配置外掛的屬性
數量:任意多個
屬性:
@property:外掛的屬性名稱
@value:該名稱所配置的值
-->
<set-property
property="pathnames"
value="/WEB-INF/validator-rules.xml,/WEB-INF/vlaidation.xml"/>
</plug-in>
</struts-config>
一、為struts配置web.xml
1,配置ActionServlet(only one),使其接收應用程式收到的所有請求
分為兩步,a:使用servlet元素配置servlet例項,做servlet-mapping
<web-app>
<servlet>
<servlet-name>storefront</servlet-name>
<servlet-class>完全限定的類名</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>storefront</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
</web-map>
2,配置初始化引數:init-param,以name/value表示<param-name><param-value>
config :預設為/WEB-INF/struts-config.xml
config/sub1:config/... 從附加的struts配置檔案中加在資程式sub1
debug:servlet的除錯detail
detail:Digester的除錯detail
convertHack
3,<taglib>使用struts提供的標記庫時必須配置包括
<taglib-uri>識別web應用程式所使用的標記庫,必須是有效的
<taglib-location>指定了標記庫描述檔案的位置
4,<welcome-file-list>配置在web app中輸入有效的,但不完整的url所使用的default resource;不使用servlet對映
<welcome-file>起始和結束都沒有/符號
5,<error-page>
(<error-code> <location>)
<<exception-type><location>
</error-page>
二、Struts配置檔案
ApplicationConfig: 包含了struts配置檔案中的所有資訊
1, <data-source>
<set-property property=““ value=““/>
<data-source>
2,<form-beans>
<form-bean name=“loginForm“ type=“完全限定的類名,是ActionForm的子類“>
<form-property name=““ type=““/>
</form-bean>
<form-bean
</form-beans>
3,<global-exceptions>
4,<global-forwards>
在Struts1.3中已經取消了<data-sources>標籤,也就是說只能在1.2版中配置,因為Apache不推薦在struts-config.xml中配置資料來源。所以建議不要在struts中配置資料來源,如果你用了hibernate或spring得話就可以在hibernate配置檔案或spring檔案配資料來源如果都沒用就到tomcat中配置