struts2工作流程及各種文件詳解
轉自:https://blog.csdn.net/zjtimef/article/details/12027767
當用戶發送一個請求後,web.xml中配置的FilterDispatche(Struts 2核心控製器)就會過濾該請求,FilterDispatcher根據配置,將請求轉發給Action。
以下是詳解過程:
1、 當Web容器收到 請求(HttpServletRequest),例如https://localhost:8080/Struts 2.0/hello.jsp就是一個請求。
2、 請求被提交到一係列的(主要有三層)過濾器(Filter),如(ActionContextCleanUp)過濾器,然後經過Other filters(SiteMesh ,etc),最後才到達FilterDispatcher,這裏是順序執行的。
3、 FilterDispatcher是控製器的核心,就是mvc的struts2實現控製層(controller)的核心。然後它調用ActionMapper確定請求那個Action,ActionMapper返回一個收集Action詳細信息的ActionMaping對象。
4、 FilterDispatcher將控製權委派給ActionProxy,ActionProxy調用配置管理器Configuration Manager(struts.xml),找到需要調用的Action類。例如上一篇的StrutsAction類就是Action類。
5、 接著ActionProxy創建一個ActionInvocation對象,ActionInvocation在調用Action之前會依次根據配置加載Action相關的所有攔截器(Interceptor )
6、 一旦Action執行完畢,ActionInvocation負責根據struts.xml中配置找到對應的返回結果result。
首先用到的是web.xml
- <span style="font-size:18px"><?xml version="1.0" encoding="UTF-8"?>
- <web-app version="2.5"
- xmlns="https://java.sun.com/xml/ns/javaee"
- xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="https://java.sun.com/xml/ns/javaee
- https://java.sun.com/xml/ns/JavaEE/web-app_2_5.xsd">
- <filter>
- <filter-name>struts 2</filter-name>
- <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
- </filter>
- <filter-mapping>
- <filter-name>struts 2</filter-name>
- <url-pattern>/*</url-pattern>
- </filter-mapping>
- </web-app>
- </span>
最上麵是普通的xml文件頭,然後是一些引用文件。後麵的webapp標簽中配置了下麵這樣一段:
…
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>所有過濾器必須實現java.Serlvet.Filter接口,這個接口中含有3個過濾器類必須實現的方法:(該過濾器類的源代碼可在struts2包中獲得)
init(FilterConfig):Servlet過濾器的初始化方法,Servlet容器創建Servlet過濾器實例後將調用這個方法。
doFilter(ServletRequest,ServletResponse,FilterChain):完成實際的過濾操作,當用戶請求與過濾器關聯的URL時,Servlet容器將先調用過濾器的doFilter方法,返回響應之前也會調用此方法。FilterChain參數用於訪問過濾器鏈上的下一個過濾器。
在該方法中將調用dispatcher.serviceAction(),該方法如果找到相應的Action,將把用戶的請求交給ActionProxy。
destroy():Servlet容器在銷毀過濾器實例前調用該方法,這個方法可以釋放Servlet過濾器占用的資源。
過濾器類編寫完成後,必須要在web.xml中進行配置,格式如下:
<filter>
<!--自定義的名稱-->
<filter-name>過濾器名</filter-name>
<!--自定義的過濾器類,注意,這裏要在包下,要加包名-->
<filter-class>過濾器對應類</filter-class>
<init-param>
<!--類中參數名稱-->
<param-name>參數名稱</param-name>
<!--對應參數的值-->
<param-value>參數值</param-value>
</init-param>
</filter>
過濾器必須和特定的URL關聯才能發揮作用,過濾器的關聯方式有3種:與一個URL資源關聯、與一個URL目錄下的所有資源關聯、與一個Servlet關聯。
① 與一個URL資源關聯:
<filter-mapping>
<!- -這裏與上麵配置的名稱要相同-->
<filter-name>過濾器名</filter-name>
<!- -與該URL資源關聯-->
<url-pattern>xxx.jsp</url-pattern>
</filter-mapping>
② 與一個URL目錄下的所有資源關聯:
<filter-mapping>
<filter-name>過濾器名</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
③ 與一個Servlet關聯:
<filter-mapping>
<filter-name>過濾器名</filter-name>
<url-pattern>Servlet名稱</url-pattern>
</filter-mapping>
struts.xml文件
- <span style="font-size:18px"><?xml version="1.0" encoding="UTF-8" ?>
- <!DOCTYPE struts PUBLIC
- "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
- "https://struts.apache.org/dtds/struts-2.0.dtd">
- <struts>
- <package name="default" extends="struts-default">
- <action name="struts" class="org.action.StrutsAction">
- <result name="success">/welcome.jsp</result>
- <result name="error">/hello.jsp</result>
- </action>
- </package>
- </struts>
- </span>
package有以下幾個常用屬性:
name(必選):指定包名,這個名字將作為引用該包的鍵。注意,包的名字必須是唯一的,在一個struts.xml文件中不能出現兩個同名的包。
extends(可選):允許一個包繼承一個或多個先前定義的包。
abstract(可選):將其設置為true,可以把一個包定義為抽象的。抽象包不能有action定義,隻能作為“父”包被其他包所繼承。
namespace(可選):將保存的action配置為不同的名稱空間。
看下麵這個例子:
- <span style="font-size:18px"><package name="default">
- <action name="foo" class="mypackage.simpleAction">
- <result name="success">/foo.jsp</result>
- </action>
- <action name="bar" class="mypackage.simpleAction">
- <result name="success">/bar.jsp</result>
- </action>
- </package>
- <package name="mypackage1" namespace="/">
- <action name="moo" class="mypackage.simpleAction">
- <result name="success">/moo.jsp</result>
- </action>
- </package>
- <package name="mypackage2" namespace="/barspace">
- <action name="bar" class="mypackage.simpleAction">
- <result name="success">/bar.jsp</result>
- </action>
- </package></span>
Action元素
當一個請求匹配到某個Action名字時,框架就使用這個映射來確定如何處理請求。
<actionname="struts" font-family:'Times New Roman';">org.action.StrutsAction">
<resultname="success">/welcome.jsp</result>
<resultname="error">/hello.jsp</result>
</action>
在上麵代碼中,當一個請求映射到struts時,就會執行該Action配置的class屬性對應的Action類,然後根據Action類的返回值決定跳轉的方向。其實一個Action類中不一定隻能有execute()方法。如果一個請求要調用Action類中的其他方法,就需要在Action配置中加以配置。例如,如果在org.action.StrutsAction中有另外一個方法為:
public String find()throws Exception{return SUCCESS;}
那麼如果想要調用這個方法,就必須在Action中配置method屬性,配置方法為:
<! - - name值是用來和請求匹配的- - >
<actionname="find" font-family:'Times New Roman';">org.action.StrutsAction"method="find">
<resultname="success">/welcome.jsp</result>
<resultname="error">/hello.jsp</result>
</action>
result元素
一個result代表一個可能的輸出。當Action類中的方法執行完成時,返回一個字符串類型的結果代碼,框架根據這個結果代碼選擇對應的result,向用戶輸出。
<result name="邏輯視圖名" type="視圖結果類型"/>
<param name ="參數名">參數值</param>
</result>
param中的name屬性有兩個值:
① location:指定邏輯視圖。
② parse:是否允許在實際視圖名中使用OGNL表達式,參數默認為true。
result中的name屬性有如下值:
success:表示請求處理成功,該值也是默認值。
error:表示請求處理失敗。
none:表示請求處理完成後不跳轉到任何頁麵。
input:表示輸入時如果驗證失敗應該跳轉到什麼地方(關於驗證後麵會介紹)。
login:表示登錄失敗後跳轉的目標。
type(非默認類型)屬性支持的結果類型有以下幾種:
chain:用來處理Action鏈。
chart:用來整合JFreeChart的結果類型。
dispatcher:用來轉向頁麵,通常處理JSP,該類型也為默認類型。
freemarker:處理FreeMarker模板。
httpheader:控製特殊HTTP行為的結果類型。
jasper:用於JasperReports整合的結果類型。
jsf:JSF整合的結果類型。
redirect:重定向到一個URL。
redirect-action:重定向到一個Action。
stream:向瀏覽器發送InputStream對象,通常用來處理文件下載,還可用於返回AJAX數據。
tiles:與Tiles整合的結果類型。
velocity:處理Velocity模板。
xslt:處理XML/XLST模板。
plaintext:顯示原始文件內容,如文件源代碼。
其中,最常用的類型就是dispatcher和redirect-action。dispatcher類型是默認類型,通常不寫,主要用於與JSP頁麵整合。redirect-action類型用於當一個Action處理結束後,直接將請求重定向到另一個Action。如下列配置:
…
<actionname="struts" font-family:'Times New Roman';">org.action.StrutsAction" >
<resultname="success">/welcome.jsp</result>
<resultname="error">/hello.jsp</result>
</action>
<actionname="login" font-family:'Times New Roman';">org.action.StrutsAction">
<result name="success"type="redirect-action">struts</result>
</action>
…
ActionSupport類
下麵是ActionSupport類所實現的接口:
- <span style="font-size:18px">public class ActionSupport implements Action, Validateable, ValidationAware,
- TextProvider, LocaleProvider,Serializable {
- }
- Action接口同樣位於com.opensymphony.xwork2包,定義了一些常量和一個execute()方法。
- public interface Action {
- public static final String SUCCESS="success";
- public static final String NONE="none";
- public static final String ERROR="error";
- public static final String INPUT="input";
- public static final String LOGIN="login";
- public String execute() throws Exception;
- }
- </span>
- <span style="font-size:18px">package org.action;
- import java.util.Map;
- import com.opensymphony.xwork2.ActionContext;
- import com.opensymphony.xwork2.ActionSupport;
- public class StrutsAction extends ActionSupport{
- private String name;
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name=name;
- }
- public String execute() throws Exception {
- if(!name.equals("HelloWorld")){
- Map request=(Map)ActionContext.getContext().get("request");
- request.put("name",getName());
- return "success";
- }else{
- return "error";
- }
- }
- }
- </span>
Action類繼承了ActionSupport類,所以可以看出,在execute的返回值中,其代碼可以改為:
…
public Stringexecute() throws Exception {
if(!name.equals("HelloWorld")){
Map request=(Map)ActionContext.getContext().get("request");
request.put("name",getName());
returnSUCCESS;
}else{
returnERROR;
}
}
…
最後更新:2017-04-03 15:21:56