閱讀264 返回首頁    go 阿裏雲 go 技術社區[雲棲]


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

  1. <span style="font-size:18px"><?xml version="1.0" encoding="UTF-8"?>  
  2. <web-app version="2.5"   
  3.     xmlns="https://java.sun.com/xml/ns/javaee"   
  4.     xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"   
  5.     xsi:schemaLocation="https://java.sun.com/xml/ns/javaee   
  6.     https://java.sun.com/xml/ns/JavaEE/web-app_2_5.xsd">  
  7.     <filter>  
  8.         <filter-name>struts 2</filter-name>  
  9.         <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>  
  10.     </filter>  
  11.     <filter-mapping>  
  12.         <filter-name>struts 2</filter-name>  
  13.         <url-pattern>/*</url-pattern>  
  14.     </filter-mapping>  
  15. </web-app>  
  16. </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文件

  1. <span style="font-size:18px"><?xml version="1.0" encoding="UTF-8" ?>  
  2. <!DOCTYPE struts PUBLIC  
  3.     "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"  
  4.     "https://struts.apache.org/dtds/struts-2.0.dtd">  
  5. <struts>  
  6.     <package name="default" extends="struts-default">  
  7.         <action name="struts" class="org.action.StrutsAction">  
  8.             <result name="success">/welcome.jsp</result>  
  9.             <result name="error">/hello.jsp</result>  
  10.         </action>  
  11.     </package>  
  12. </struts>  
  13. </span>  


package
有以下幾個常用屬性:


name(必選):指定包名,這個名字將作為引用該包的鍵。注意,包的名字必須是唯一的,在一個struts.xml文件中不能出現兩個同名的包。

extends(可選):允許一個包繼承一個或多個先前定義的包。

abstract(可選):將其設置為true,可以把一個包定義為抽象的。抽象包不能有action定義,隻能作為“父”包被其他包所繼承。

namespace(可選):將保存的action配置為不同的名稱空間。

看下麵這個例子:

  1. <span style="font-size:18px"><package name="default">  
  2.     <action name="foo" class="mypackage.simpleAction">  
  3.         <result name="success">/foo.jsp</result>  
  4.     </action>  
  5.     <action name="bar" class="mypackage.simpleAction">  
  6.         <result name="success">/bar.jsp</result>  
  7.     </action>  
  8. </package>  
  9. <package name="mypackage1" namespace="/">  
  10.     <action name="moo" class="mypackage.simpleAction">  
  11.         <result name="success">/moo.jsp</result>  
  12.     </action>  
  13. </package>  
  14. <package name="mypackage2" namespace="/barspace">  
  15.     <action name="bar" class="mypackage.simpleAction">  
  16.         <result name="success">/bar.jsp</result>  
  17.     </action>  
  18. </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整合的結果類型。

jsfJSF整合的結果類型。

redirect:重定向到一個URL

redirect-action:重定向到一個Action

stream:向瀏覽器發送InputStream對象,通常用來處理文件下載,還可用於返回AJAX數據。

tiles:與Tiles整合的結果類型。

velocity:處理Velocity模板。

xslt:處理XML/XLST模板。

plaintext:顯示原始文件內容,如文件源代碼。

其中,最常用的類型就是dispatcherredirect-actiondispatcher類型是默認類型,通常不寫,主要用於與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類所實現的接口:

  1. <span style="font-size:18px">public class ActionSupport implements Action, Validateable, ValidationAware,  
  2.         TextProvider, LocaleProvider,Serializable {  
  3. }  
  4. Action接口同樣位於com.opensymphony.xwork2包,定義了一些常量和一個execute()方法。  
  5. public interface Action {  
  6.     public static final String SUCCESS="success";  
  7.     public static final String NONE="none";  
  8.         public static final String ERROR="error";  
  9.         public static final String INPUT="input";  
  10.     public static final String LOGIN="login";  
  11.         public String execute() throws Exception;  
  12. }  
  13. </span>  
Action類

  1. <span style="font-size:18px">package org.action;  
  2. import java.util.Map;  
  3. import com.opensymphony.xwork2.ActionContext;  
  4. import com.opensymphony.xwork2.ActionSupport;  
  5. public class StrutsAction extends ActionSupport{  
  6.     private String name;  
  7.     public String getName() {  
  8.         return name;  
  9.     }  
  10.     public void setName(String name) {  
  11.         this.name=name;  
  12.     }  
  13.     public String execute() throws Exception {  
  14.         if(!name.equals("HelloWorld")){  
  15.             Map request=(Map)ActionContext.getContext().get("request");  
  16.             request.put("name",getName());  
  17.             return "success";  
  18.         }else{  
  19.             return "error";  
  20.         }  
  21.     }  
  22. }  
  23. </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

  上一篇:go 文件監控(教學版)
  下一篇:go Spark-0.8 release新增特性及看點