Struts2框架基本使用


 

時間:2017-1-6 16:53

 

修改struts.xml配置文件不需要重啟服務器。


Struts2框架

    一、
        *   介紹Struts2
        *   關於Struts2配置(關於Action配置)
        *   關於Struts2結果類型
    二、
        *   Struts2處理請求參數
        *   Struts2的類型轉換(了解)
        *   Struts2的校驗
    三、
        *   Struts2的國際化
        *   Struts2的攔截器
        *   Struts2文件上傳與下載
        *   Struts2中ognl與valuestack
    四、
        *   ognl與valuestack
        *   Struts2中的防止表單重復提交
        *   Struts2中的Ajax插件
    五、
        *   練習(增刪改查)


——什么是Struts2 

1、Struts2是一個非常優秀的MVC框架,基於Model2設計模型,只能在JavaWeb項目中應用。

2、由傳統Struts1和WebWork兩個經典框架發展而來。

3、Struts2核心功能
    *   允許POJO(Plain Old Java Object)對象作為Action。
    *   Action的excute方法不再與Servlet API耦合,更容易測試。
    *   支持更多視圖技術(JSP、FreeMarker、Velocity)。
    *   基於Spring AOP思想的攔截器機制,更易擴展。
    *   更強大、更易用的輸入校驗功能。
    *   整合Ajax支持

4、Struts2核心:WebWork
    WebWork核心是XWork,XWork提供了很多核心功能:前端攔截器(Interceptor),運行時表單屬性驗證,類型轉換,強大的表達式語言,(OGNL - the Object Graph Navigation Language),IoC(Inversion of Control 反轉控制)容器等。

——Struts2的下載和安裝

1、到http://struts.apache.org/download.cgi 去下載Struts2最新版本。

2、Struts2目錄結構
    *   apps:該文件包含了基於Struts2的示例應用。
    *   docs:該文件夾下包含了Struts2相關文檔,包括Struts2快速入門、Struts2的文檔以及API等文檔。
    *   lib:該文件夾下包含了Struts2框架和核心類庫,以及Struts2第三方插件類庫
    *   src:該文件夾下包含了Struts框架的全部源代碼。
        >   core:Struts2的源代碼
        >   xwork-core:xwork的源代碼

3、開發時沒必要將lib目錄下的jar文件全部復制到項目中。
    可以到:struts-2.3.15.1\apps\struts2-blank\WEB-INF\lib目錄下找到必要jar包。

——Struts2之HelloWorld

Struts2的Web項目盡量使用JavaEE5.0版本,因為Struts2是基於配置文件進行開發的。

1、導入jar包
    struts-2.3.15.1\apps\struts2-blank\WEB-INF\lib目錄下找到必要jar包即可。

2、創建index.jsp、hello.jsp頁面

3、對Struts2框架進行配置
    1)web.xml文件中配置前端控制器(核心控制器),其實就是一個Filter,目的是使Struts2框架生效。
        該過濾器的init()方法加載了Struts2框架必要的配置文件。

        <filter>
            <filter-name>struts2</filter-name>
            <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
        </filter>
 
        <filter-mapping>
            <filter-name>struts2</filter-name>
            <url-pattern>/*</url-pattern>
        </filter-mapping>
 

    2)創建一個struts.xml配置文件,這個是Struts2框架的配置文件,目的是使Struts2的流程可以執行。
        名稱:struts.xml
        位置:src文件夾下(classes文件夾下)

 

4、創建一個HelloAction類
    要求:在HelloAction類中創建一個返回值是String類型的無參方法。

    public String hello(){
        return "hello";
    }


5、在struts.xml文件中配置HelloAction

<struts>
    <package name="default" namespace="/" extends="struts-default">
        <action name="hello" class="com.wyc.action.HelloAction" method="hello">
            <result name="hello">/hello.jsp</result>
        </action>
    </package>
</struts>


6、在index.jsp中添加鏈接,進行測試:
    <a href="${pageContext.request.contextPath }/hello" >第一次使用Struts2</a>

    在地址欄中輸入:http://localhost/struts2_day01/index.jsp,訪問超鏈接,就可以看到HelloAction類中的hello方法執行了,並且跳轉到了hello.jsp頁面。

7、流程分析:

圖片

8、手寫代碼實現Struts2功能
    1)創建一個Filter:StrutsFilter
    2)在web.xml文件中配置StrutsFilter
    3)在StrutsFilter中攔截操作,並訪問Action中的方法,跳轉到hello.jsp頁面。

=============================================================================
示例代碼:

struts.xml文件:

<struts>
    <action name="hello" class="com.wyc.action.HelloAction" method="hello">
        <result name="hello">/hello.jsp</result>
        <result name="hello2">/hello2.jsp</result>
    </action>
</struts>


----------------------------------------------------------------------------------------------------------------------------

StrutsFilter:

package com.wyc.web.filter;
 
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Method;
 
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
 
public class StrutsFilter implements Filter {
 
    public void destroy() {
 
    }
 
    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
        // 1、強轉
        HttpServletRequest request = (HttpServletRequest)req;
        HttpServletResponse response = (HttpServletResponse)resp;
 
        /*
         * 2.1、得到請求資源路徑
         */
        // 得到請求路徑
        // uri:/Struts_day01_1/hello
        String uri = request.getRequestURI();

        // 得到項目名
        // contextPath:/Struts_day01_1
        String contextPath = request.getContextPath();
 
 
        // hello
        String path = uri.substring(contextPath.length()+1); 
 
 
        /*
         * 使用path去struts.xml文件中查找某一<action name=path>
         */
        SAXReader reader = new SAXReader();
        try {
            Document doc = reader.read(new File(this.getClass().getClassLoader().getResource("struts.xml").getPath()));
 
            Element action = (Element) doc.selectSingleNode("//action[@name='" + path + "']"); // "//action['hello']"
 
            if(action != null){
                // 得到action元素的class屬性和method屬性
                String className = action.attributeValue("class");
                String methodName = action.attributeValue("method");
 
 
                // 通過反射得到Class對象,然后得到Method對象
                Class c = Class.forName(className);
                Method method = c.getDeclaredMethod(methodName);
 
 
                // 執行method方法,並獲取返回值
                String returnValue = (String) method.invoke(c.newInstance());
 
 
                // 使用返回的字符串去<action>下查找其子元素result的name屬性值,獲取與返回字符串相同的<result>元素
                Element e = (Element) action.selectSingleNode("//result[@name='" + returnValue + "']");
 
                if(e != null){
                    // 表示result存在,可以執行跳轉
                    String skipPath = e.getText();
 
 
                    request.getRequestDispatcher(skipPath).forward(request, response);
                    return;
                }
 
            }
 
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
 
 
        // 3、放行
        chain.doFilter(req, resp);
    }
 
    public void init(FilterConfig arg0) throws ServletException {
 
    }
 
}

------------------------------------------------------------------------------------------------------------------

HelloAction.java

package com.wyc.action;
 
public class HelloAction {
    public String hello(){
        System.out.println("hello");
        return "hello";
    }
}
=======================================================================



——Struts2的流程分析與工具配置

1、運行流程:
    請求  -->  StrutsPrepareAndExecuteFilter(核心控制器、核心攔截器、前端控制器、前端攔截器)  -->  Interceptors(攔截器,實現代碼功能,核心是AOP動態代理)  -->  Action的execute  -->  Result(結果頁面)

    攔截器:在struts-default.xml中定義
    執行攔截器:在defaultStack中引用攔截器

    可以通過源碼級別斷點調試,證明攔截器執行了(學會導入源碼,選中完整類名,然后ctrl + t)。

圖片


2、手動配置struts.xml文件中提示操作
    1)復制http://struts.apache.org/dtds/struts-2.3.dtd
        到該目錄中查找dtd文件:struts-2.3.15.1\src\core\src\main\resources
    2)在Windows —— Preferences —— 輸入XML —— XML Catalog —— Add ——在Location中填入dtd文件路徑 ——Key type選擇URI —— URI中填入(名稱空間):http://struts.apache.org/dtds/struts-2.3.dtd —— OK

    導入DTD時,應該和配置DTD版本一致。

3、關聯Struts2的源文件
    Ctrl + Shift + t,輸入類名查找對應類,然后關聯源碼。
    如果是com.opensymphony.xxx,就在xwork-core目錄中查找。
    如果是org.apache.struts2.xxx,就在core目錄中查找

4、使用ConfigBroswer插件(了解)
    提供在瀏覽器中查看Struts2配置加載情況。
    將解壓后的struts2/lib/struts2-config-browser-plugin-2.3.7.jar復制到WEB-INF/lib目錄下
    訪問:localhost:8080/struts2_day01/config-browser/index.action查看struts2配置加載情況。

——Struts2配置(重點)

1、Struts2配置文件加載順序:
    1)Struts2框架要想執行,必須先加載StrutsPrepareAndExecuteFilter
        在StrutsPrepareAndExecuteFilter類的init()方法中對Dispatcher進行了初始化操作。
        在Dispatcher類中定義的init()方法內就描述了Struts2配置文件的加載順序:

 
            init_DefaultProperties(); // [1] —— struts2-core-2.3.15.1.jara包中的org/apache/struts2/default.properties
            init_TraditionalXmlConfigurations(); // [2] —— struts2-core-2.3.15.1.jara包中的struts-default.xml, struts-plugin.xml, struts.xml
            init_LegacyStrutsProperties(); // [3] —— 自定義struts.properties
            init_CustomConfigurationProviders(); // [5] —— 自定義配置文件
            init_FilterInitParameters() ; // [6] —— web.xml
            init_AliasStandardObjects() ; // [7] —— 加載Bean

            第一個加載的文件:default.properties文件
                作用:定義了Struts2框架中所有常量。
                位置:org/apache/struts2/default.properties

                properties文件定義鍵值對,定義值。
                XML文件定義關系。


            第二個加載的文件:
                struts-default.xml:
                    作用:配置了bean, interceptor, result等信息。
                    位置:struts2-core-2.3.15.1.jara包中。
                struts-plugin.xml
                    它是struts2框架中所使用的插件的配置文件。
                struts.xml
                    使用struts2框架所使用的配置文件。

            第三個加載的文件:自定義的struts.properties
                可以自定義常量,而不是用struts.properties中定義的常量。

            第四個加載的文件:web.xml

        在開發中,后加載文件中的配置會將先加載文件中的配置覆蓋。

——關於Action的配置(重點)

1、struts.xml
    1)<package>:
            用於聲明一個包,管理Action類。(通常情況下一個模塊一個package)
            Struts2所有action都通過package管理。
            struts-default是struts-default.xml定義的一個package,其中包含大量攔截器和結果集。
            Action的訪問路徑 = namespace + action的name屬性

        *   name
            包名,用於聲明一個包名,包名不能重復。

        *   namespace
            與<action>元素的name屬性合並,確定了一個唯一可以訪問Action類的路徑。
 
        *   extends
            表示繼承的包名。

        *   abstract
            可以取值為true或false,(true)表示可以用於繼承。

    2)<action>
            用於聲明一個Action類。
        *   name
            表示一個Action類的名稱,在同一個包內,Action的名稱是唯一的。
            它與<package>元素中的namespace屬性確定了一個訪問Action類的路徑。

        *   class
            Action類的完整包名

        *   method(請求處理方法)
            表示要訪問的Action類中的方法的名稱。

    3)<result>
            用於確定返回結果。

        *   name
            與Action類中的方法返回值做對比,確定跳轉路徑。

        *   type
            確定跳轉處理方式。

2、關於Action配置其他細節
    1)默認值:
        <package namespace="默認值">
            *   namespace的默認值是"/";

        <action class="默認值" method="默認值">
            *   class的默認值:com.opensymphony.xwork2.ActionSupport
            *   method默認值:ActionSupport類中的execute()方法

        <result name="默認值">
            *   name的默認值是execute()方法的返回值return SUCCESS;,也就是"success"。

    2)關於訪問Action的路徑問題
        現在的Action配置是:
            <package name="default" namespace="/" extends="struts-default">
                <action name="hello" class="com.wyc.action.DefaultAction">
                    <resule>/hello.jsp</result>
                </action>
            </package>

        當輸入:http://localhost/Struts2_day01_2/a/b/c/hello時,也可以訪問到Action類。

        因為:Struts2中的Action被訪問時,它會首先查找:
            1: namespace="/a/b/c"    action的name=hello,沒有找到
            2: namespace="/a/b"       action的name=hello,沒有找到
            3: namespace="/a"          action的name=hello,沒有找到
            4: namespace="/"            action的name=hello,找到了

            如果最后也查找不到,會報404錯誤。

    3)默認的處理請求Action
        作用:處理其他Action處理不了的路徑。
        <default-action-ref name="action的name屬性" />
        配置這個元素后,當所有的Action無法處理訪問路徑時,會執行name指定的<action>元素。
        只在同包中有效。

    4)Action的默認處理類
        在Action配置時,如果不寫class屬性,默認是:comm.opensymphony.xwork2.ActionSupport。
        <default-class-ref class="com.wyc.action.DefaultAction"/>
        配置這個元素后,在當前包中,如果<action>元素不寫class屬性,那么默認處理Action請求的處理類就為class指定的類。
        只在同包中有效。

3、關於Struts2中的常量配置
    在default.properties文件中聲明了Struts2中的常量。

    可以在哪些文件中配置常量?
        *   struts.xml(應用最多)
            >   <constant name="常量名稱" value="常量值"></constant>
        *   struts.properties(基本不用)
        *   web.xml(了解)
            >   在<filter>元素下通過<init-param>初始化參數進行配置。
            >   在web.xml文件中配置的常量會覆蓋struts.xml文件中的配置。

    1)常用常量:
        *   struts.action.extension=action,,
            這個常量用於指定Struts2框架默認攔截的后綴名,例如:
                localhost/Struts2_day01/hello.action(可以訪問)
                localhost/Struts2_day01/hello(可以訪問)
                localhost/Struts2_day01/hello.abc(不可以訪問)
            在struts.xml文件中設置:
                <constant name="struts.action.extension" value="abc,,"></constant>
            運行結果如下:
                localhost/Struts2_day01/hello.action(不可以訪問)
                localhost/Struts2_day01/hello(可以訪問)
                localhost/Struts2_day01/hello.abc(可以訪問)

        *   struts.i18n.encoding=UTF-8
            相當於request.setCharacterEncoding("UTF-8");,可以解決POST請求的亂碼問題。

        *   struts.serve.static.browserCache=false
            false表示不緩存,true表示瀏覽器會緩存靜態內容,產品環境設置true,開發環境設置false。

        *    struts.devMode=true
            DevelopModel,開發模式,相當於熱部署。
            修改struts.xml文件后不需要重啟服務器。
            提供詳細報錯頁面,而不是只顯示404等錯誤信息。

        *   struts.configuration.xml.reload=true
            當struts的配置文件修改后,系統是否自動重新加載該文件,默認值為false(生產環境下使用),開發階段最好打開 



4、struts.xml文件的分離
    因為多個模塊的package太多會影響閱讀,為了方便閱讀,所以可以讓一個模塊保存一個配置文件,將多個package分離,使用時引入配置文件即可。
    引入方式:
        <include file="文件路徑" />

——Action類的創建方式

1、有三種創建方式:
    1)創建一個POJO類(直接創建一個class)
        POJO類表示沒實現任何接口,沒繼承任何父類,除了Object類。
        優點:無耦合。
        缺點:所有工作都要自己實現,代碼量大。

        底層通過反射來實現:
            Struts2框架讀取struts.xml獲得完整Action類名 —— object = Class.forName(完整類名).newInstance() —— Method m = obj.getMethod("execute"); —— m.invoke(obj); 通過反射執行execute()方法。

    2)實現Action接口
        為了讓用戶開發的Action更加規范,Struts2提供了一個Action接口。
        創建一個類,實現Action接口:com.opensymphony.xwork2.Action
        優點:耦合低,提供了五種邏輯視圖(字符串常量),定義了一個行為方法(execute())。
        缺點:所有工作都要自己實現,但是已經得到標准規范。

        五種邏輯視圖:(Action處理數據后進行頁面跳轉)
            public static final String SUCCESS = "success";    // 數據處理成功(成功頁面)
            public static final String NONE = "none";    // 頁面不跳轉,與return null 效果相同
            public static final String ERROR = "error";    // 數據處理發送錯誤(錯誤頁面)
            public static final String INPUT = "input";    // 用戶輸入數據有誤,通常用於校驗表單數據
            public static final String LOGIN = "login";    // 主要權限認證(登錄頁面)

        示例代碼:
            public class HelloAction implements Action {
                public String execute(){
                    System.out.println("hello");
                    return "success";
                }
            }

    3)繼承ActionSupport(推薦)
        com.opensymphony.xwork2.ActionSupport類實現了Action接口。
        優點:功能比較完善,ActionSupport支持校驗(實現Validateable接口)、錯誤信息設置、支持國際化(實現LocaleProvider接口)
        缺點:耦合度高。

        示例代碼:
            public class HelloAction2 extends ActionSupport {
                @Override
                public String execute(){
                    System.out.println("hello");
                    // return "success";
                    return NONE; // 相當於return null;
                }
            }

——關於Action的訪問

如果沒有指定method屬性,則默認執行execute()方法。

1、通過設置method的屬性值,來確定訪問action類中的哪一個方法。

    <package name="book" namespace="/" extends="struts-default">
        <action name="book_add" class="com.wyc.action.BookAction" method="add"></action>
        <action name="book_update" class="com.wyc.action.BookAction" method="update"></action>
        <action name="book_delete" class="com.wyc.action.BookAction" method="delete"></action>
        <action name="book_search" class="com.wyc.action.BookAction" method="search"></action>
    </package>

    當訪問book_add時,會調用BookAction類中的add方法,以此類推。

2、使用通配符來簡化配置
    1)在struts.xml文件中配置:
        <action name="*_*" class="com.wyc.action.{1}Action" method="{2}"></action>

    2)在JSP頁面中創建兩個頁面:book.jsp、product.jsp
        book.jsp:
            <body>
                <a href="${pageContext.request.contextPath }/Book_add">book add</a>
                <a href="${pageContext.request.contextPath }/Book_update">book update</a>
                <a href="${pageContext.request.contextPath }/Book_delete">book delete</a>
                <a href="${pageContext.request.contextPath }/Book_search">book search</a>
            </body>

        product.jsp:
            <body>
                <a href="${pageContext.request.contextPath }/Product_add">product add</a>
                <a href="${pageContext.request.contextPath }/Product_update">product update</a>
                <a href="${pageContext.request.contextPath }/Product_delete">product delete</a>
                <a href="${pageContext.request.contextPath }/Product_search">product search</a>
            </body>

        當訪問book add時,這時的路徑是:Book_add,那么對於struts.xml文件中第一個“*”就是Book,第二個“*”就是add。
        對於{1}Action就相當於BookAction,對於method="{2}",就相當於method="add"

    3)、使用通配符配置時注意事項:
       *   必須定義一個統一的命名規范
       *   不建議使用過多的通配符,影響閱讀性

3、動態方法調用(了解)
    在struts.xml文件中配置:
        <action name="book" class="com.wyc.action.BookAction"></action>
    訪問: http://localhost/Struts2_day01_2/book!add
    就可以訪問到BookAction類中的add方法了。

    book!add就是動態方法調用,嘆號后面寫的就是方法名。

    注意:
        Struts2框架支持動態方法調用,可以在default.properties中設置動態方法調用為true
        struts.enable.DynamicMethodInvocation = true

——在Struts2框架中獲取Servlet API

對於Struts2框架,不建議直接使用Servlet API。

在Struts2中獲取Servlet API有三種方式:
    1、通過ActionContext獲取
        *   獲取一個ActionContext對象
            >   ActionContext context = ActionContext();
        *   獲取Servlet API
            >   通過ActionContext獲取到的不是真正的Servlet API,而是一個Map集合,集合中存放的就是對象(用鍵值對)存放的數據。
    2、通過注入方式獲取
    3、通過ServletActionContext獲取

----------------------------------------------------------------------------------------------------------------------------

1、Action訪問Servlet
    在Action中用解耦和方式使用ActionContext對象間接訪問Servlet API。
    在Struts2中Action API已經與Servlet API解耦和了(沒有依賴關系)。
    Servlet API常見操作:
        *   獲取表單提交請求參數
        *   向request, session, application三個作用域存取數據

    開發中應優先使用ActionContext,這樣可以避免耦合。

ActionContext方法:
    *   Map  getParameters()
        獲取所有請求參數的Map集合。
        Map底層是一個HashMap。

    *   void  put(String key, Object value)
        對request域存放數據。

    *   Map  getApplication()
        獲取ServletContext數據Map,對應用訪問存取數據。

    *   Map  getSession()
        獲取session數據Map,對Session范圍存取數據。

/*
 * 通過ActionContext獲取Servlet API
 */
public class ServletDemo1Action extends ActionSupport {
 
    @Override
    public String execute() throws Exception {
        /*
         * 1、獲取ActionContext對象
         */
        ActionContext context = ActionContext.getContext();
 
        /*
         * 2、獲取Servlet API
         */
 
        // 獲取application中數據
        Map<String, Object> applicationMap = context.getApplication();
        System.out.println("application: " + applicationMap.get("aname"));
 
        // 獲取session中數據
        Map<String, Object> sessionMap = context.getSession();
        System.out.println("session: " + sessionMap.get("sname"));
 
        return NONE;
    }
}

----------------------------------------------------------------------------------------------------------------------------

2、使用接口注入的方式操作Servlet API(耦合)
    這種方式能夠真正獲取到Web對象。

    步驟:
        1)要求Action類必須實現指定接口:
            ServletContextAware接口:注入ServletContext對象
            ServletRequestAware接口:注入request對象
            ServletResponseAware接口:注入response對象
        2)重寫接口中指定的方法:
            public void setServletRequest(HttpServletRequest request)
        3)聲明一個web對象,使用接口中的方法對聲明的web對象賦值
            private HttpServletRequest request;
            public void setServletRequest(HttpServletRequest request){
                this.request = request;
            }

    示例代碼:

        /*
         * 通過注入方式獲取Servlet API
         */
        public class ServletDemo2Action extends ActionSupport implements ServletRequestAware {
            private HttpServletRequest request;
 
            public String execute() {
 
                System.out.println(request.getParameter("username"));
 
                return null;
            }
 
            /*
             * 實現接口方法
             */
            public void setServletRequest(HttpServletRequest request) {
                this.request = request;
            }
        }


    分析其實現方法:
        通過Struts2的interceptor實現的。
        struts-default.xml:
            <interceptor name="servletConfig" class="org.apache.struts2.interceptor.ServletConfigInterceptor"/>
        源碼:
            org.apache.struts2.interceptor.ServletConfigInterceptor攔截器中的intercept()方法:
                public String intercept(ActionInvocation invocation) throws Exception {
                    final Object action = invocation.getAction();
                    final ActionContext context = invocation.getInvocationContext();
 
                    if (action instanceof ServletRequestAware) {    // 判斷Action類是否實現了ServletRequestAware接口
                        HttpServletRequest request = (HttpServletRequest) context.get(HTTP_REQUEST);    // 得到request對象
                        // 因為action是Object類型,所以需要強轉 
                        ((ServletRequestAware) action).setServletRequest(request);    // 將request對象通過Action中重寫的方法注入,
                    }
                    ....... 
                    return invocation.invoke();
                }

----------------------------------------------------------------------------------------------------------------------------

3、通過ServletActionContext獲取Servlet API
    在ServletActionContext中方法都是靜態的。
    該類的父類是ActionContext,其內部代碼也是通過ActionContext獲取到的。

    方法概要:
        static PageContext  getPageContext()
            獲取PageContext對象。

        static HttpServletRequest  getRequest()
            獲取request對象。

        static HttpServletResponse  getResponse()
            獲取response對象。

        static ServletContext  getServletContext()
            獲取ServletContext對象。

        沒有getSession()方法,但是可以通過getPageContext().getSession()獲得。
        有了pageContext,其它八個對象都可以得到。

    示例代碼:

        /*
         * 通過ServletActionContext獲取Servlet API
         */
        public class ServletDemo3Action extends ActionSupport {
            public String execute() {
 
                HttpServletRequest request = ServletActionContext.getRequest();
 
                System.out.println(request.getParameter("username"));
 
                return null;
            }
        }

——Result結果類型

在:struts-default.xml文件中定義。

1、理解處理結果
    *   Action處理完用戶請求后,會返回一個普通字符串。
    *   整個普通字符串就是一個邏輯視圖名。
    *   Struts2根據邏輯視圖名,決定運行哪個結果。
    *   Struts2處理結果使用<result>元素進行配置。
        >   局部結果:將<result>作為<action>的子元素進行配置
        >   全局結果:將<result>作為<global-result>的子元素進行配置
    *   配置<result>元素通常需要指定兩個屬性
        >   name:該屬性指定配置邏輯視圖名
        >   type:該屬性指定結果類型(跳轉方式、處理方式)

2、<result>標簽屬性:
    *   name屬性:
        與action中的method的返回值匹配,獲取跳轉路徑,進行跳轉。

    *   type屬性:
        作用是定義跳轉方式。
        對於type屬性的取值范圍有以下幾種:(可以在struts-default.xml文件中查看)
        >   chain:請求轉發,一般情況下用於從一個Action跳轉到另一個Action。
        >   dispatcher:請求轉發,是默認值,一般用於從Action跳轉到jsp頁面。
        >   freemarker:模板技術,將頁面與數據分離,通過freemarker將數據和頁面整合到一起。
        >   httpheader
        >   plainText
        >   redirect:重定向,一般用於從Action重定向到頁面。
        >   redirectAction:重定向,一般用於從Action重定向到另一個Action。
            redirectAction有兩個參數:
                actionname:指定目標Action的名稱,它是默認屬性。
                namespace:用來指定目標Action的名稱空間,默認為"/"。 
        >   stream:代表從服務器端返回一個流,一般用於下載。
        >   velocity:模板引擎
        >   xslt

    <package name="struts-default" abstract="true">
        <result-types>
            <result-type name="chain" class="com.opensymphony.xwork2.ActionChainResult"/>
            <result-type name="dispatcher" class="org.apache.struts2.dispatcher.ServletDispatcherResult" default="true"/>
            <result-type name="freemarker" class="org.apache.struts2.views.freemarker.FreemarkerResult"/>
            <result-type name="httpheader" class="org.apache.struts2.dispatcher.HttpHeaderResult"/>
            <result-type name="redirect" class="org.apache.struts2.dispatcher.ServletRedirectResult"/>
            <result-type name="redirectAction" class="org.apache.struts2.dispatcher.ServletActionRedirectResult"/>
            <result-type name="stream" class="org.apache.struts2.dispatcher.StreamResult"/>
            <result-type name="velocity" class="org.apache.struts2.dispatcher.VelocityResult"/>
            <result-type name="xslt" class="org.apache.struts2.views.xslt.XSLTResult"/>
            <result-type name="plainText" class="org.apache.struts2.dispatcher.PlainTextResult" />
        </result-types>
    </package>

    必須掌握:
        chain、dispatcher、redirect、redirectAction、stream
        兩個轉發、兩個重定向、一個流。 
    了解:freemarker、velocity

3、局部結果頁面與全局結果頁面
    當多個action中都是用了相同的result,這時可以把result定義為全局結果頁面。
<struts>
    <package name="default" namespace="/" extends="struts-default">
 
        <!-- 全局結果,當前package中的Action都可以使用 -->
        <global-results>
            <result>/demo2_success.jsp</result>
            <!-- 當存在多個result時,以后面的result為准 -->
            <result>/demo1_success.jsp</result>
        </global-results>

        <action name="demo1" class="com.wyc.action.ServletDemo1Action">
            <!-- 局部結果,僅限當前Action使用 -->
            <result>/demo1_success.jsp</result>
        </action>
        <action name="demo2" class="com.wyc.action.ServletDemo2Action">
            <!-- 如果當前action下沒有result,那么就會到全局中查找 -->
        </action>
        <action name="demo3" class="com.wyc.action.ServletDemo3Action"></action>
    </package>
</struts>

——練習:登錄操作

1、需求:
    用戶通過表單進行登錄,登陸失敗將頁面轉發到login.jsp,並顯示錯誤信息。
    登錄成功后將用戶存儲到Session中,重定向到success.jsp頁面,並展示用戶信息。

2、所需頁面
    login.jsp
        >   提供登錄表單
        >   登錄失敗時顯示錯誤信息
    success.jsp
        >   登錄成功后通過session獲取用戶信息並顯示到頁面
 
3、所需類
    LoginAction
        >   獲取Servlet API,獲取表單信息
        >   校驗用戶信息
            >   登錄成功,重定向到success.jsp
            >   登錄失敗,轉發到login.jsp
    User類
        實體類
        >   private String username;
        >   private String password;

——總結

    1、Struts2環境搭建
        *   導入jar包:
            >   struts2/apps/strut_blank.war文件
        *   web.xml如何配置:
            >   配置StrutsPrepareAndExecuteFilter
        *   struts.xml如何配置:
            >   在src目錄下(classes)
    2、Struts2運行流程
        *   如何通過反射執行action
    3、配置文件加載順序
        *   每個配置文件的用途是什么
        1)default.properties
        2)struts-default.xml  struts-plugin.xml  struts.xml
        3)struts.properties
        4)web.xml 
    4、<package><action><result>元素的配置
        *   package:用於管理action
            >   name:包名,唯一
            >   namespace:與action的name屬性確定訪問action的路徑。
            >   extends:繼承的包名,一般繼承struts-default
        *   action:聲明一個action
            >   name:action名稱,在同一個包下不能重名
            >   class:action完整類名,默認是ActionSupport
            >   method:action類中的方法名,要求無參,返回值為String,默認值為execute
        *   result:結果視圖
            >   name:與action的method方法的返回值進行匹配確定跳轉路徑
            >   type:跳轉方式
                在struts-default.xml文件中定義:
                    chain, dispatcher, redirect, redirectAction, stream
    5、Action的三種創建方式
        *   POJO
        *   實現Action接口
        *   繼承ActionSupport類
    6、指定method的調用方法
        *   指定method屬性
        *   通配符
        *   動態方法調用
    7、Action訪問Servlet API
        *   ActionContext
        *   訪問指定接口(注入)
        *   ServletActionContext
    8、結果類型
        *   <result>標簽的type屬性取值。
    9、自定義常量
        *   在struts.xml文件中定義
            >   <constant name="" value="" />
        *   在struts.properties文件中定義
        *   在web.xml文件中定義 
            >   <init-param></initparam>
 
——Struts2核心知識點及問題

1、struts2在web.xml配置的Filter叫什么?
2、struts2的Action有幾種書寫方式?
3、能否在struts2的Action定義多個業務方法?如何做到不同的請求訪問Action的不同方法?
4、自定義struts2類型轉換器實現實現哪個接口,如何配置局部轉換器和全局轉換器?
5、struts2的國際化信息文件有哪幾類?
6、xml進行struts2請求參數校驗時,指定方法的校驗文件和所有方法校驗文件命名規則是什么?
7、struts2的Action中如何使用ServletAPI?
8、簡單描述struts2的值棧對象的內部存儲結構
9、addFieldError、addActionError和addActionMessage 有何區別?
10、struts2中有哪些常用結果類型?你用過哪些?
11、你是否在struts2開發中 自定義過攔截器,實現什么功能?
12、struts2 UI主題有哪些?你用過哪些? 底層實現是什么?
13、struts2 和 struts1 有何區別?
14、struts2 中如何使用 Ajax ?
15、struts2 的攔截器使用了哪種設計模式 ?
 
——關於Struts2中約定訪問規則

從struts2.1開始,struts2 引入了Convention插件來支持零配置
使用約定無需struts.xml或者Annotation配置
需要 struts2-convention-plugin-2.3.7.jar 、asm-*.jar(三個)
插件會自動搜索action、actions、struts、struts2包下所有Java類
所有實現了com.opensymphony.xwork2.Action的Java類
所有類名以Action結尾的Java類
下面類名都符合Convention插件
cn.itcast.struts2.HelloAction
cn.itcast.actions.books.BookSearchAction
cn.itcast.struts.user.UserAction
cn.itcast.estore.action.test.LoginAction
 
 
struts2-convention-plugin-2.3.7.jar 中struts-plugin.xml重要常量
<constant name="struts.convention.package.locators" value="action,actions,struts,struts2"/>  默認掃描包
<constant name="struts.convention.exclude.packages" value="org.apache.struts.*,org.apache.struts2.*,org.springframework.web.struts.*,org.springframework.web.struts2.*,org.hibernate.*"/> 不掃描
<constant name="struts.convention.action.suffix" value="Action"/> 默認掃描以Action結尾的類
<constant name="struts.convention.result.path" value="/WEB-INF/content/"/> 結果result頁面存放位置
<constant name="struts.convention.classes.reload" value="false" /> Action類文件重新自動加載
 
如果Action類名包含Action后綴,將Action后綴去掉
將Action類名的駝峰寫法,轉成中划線寫法
例如:
cn.itcast.struts2.HelloAction 映射到 /hello.action
cn.itcast.actions.books.BookSearchAction  映射到 /books/book-search.action
cn.itcast.struts.user.UserAction 映射到 /user/user.action
cn.itcast.estore.action.test.LoginAction 映射到 /test/login.action
 
默認情況下,Convention總會到Web應用的WEB-INF/content路徑下定位結果資源
<constant name="struts.convention.result.path" value="/WEB-INF/content/"/>
約定: actionName + resultCode + suffix 
例如:
訪問cn.itcast.struts.user.UserAction返回success
Convention優先使用 WEB-INF/content/user/user-success.jsp
如果user-success.jsp不存在,會使用user-success.html
如果user-success.html不存在,會使用user.jsp


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM