1. 程式人生 > >day30Struts2Day01( Servlet Action 萬用字元方式訪問 過濾器)

day30Struts2Day01( Servlet Action 萬用字元方式訪問 過濾器)

框架的概念
1、什麼是Struts2的框架
    Struts2是Struts的下一代產品,是在struts1和WebWork的的技術基礎上進行了合併的全新的Struts2框架
    其全新的Struts2的體系結構與Struts2結構差別巨大
    Struts2以WebWork為核心,採用攔截器的機制來處理使用者的請求,這樣的設計也使得業務邏輯控制器能夠與ServletAPI完全脫離開,所以Struts2可以理解為WebWork的更新產品
    雖然從Struts1到Struts2有太大的變化,但是相對於WebWork,Struts2的變化很小

2、Struts2是一個基於MVC設計模式的Web層框架
    MVC和JavaEE的三層結構
        MVC設計模式,是由一些網站的開發人員提出來的
        JavaEE三層結構:SUN公司為EE開發劃分的結構
3、常見的Web層的框架
    Struts1
    Struts2
    WebWork
    SpringMVC
4、Web層框架的特點
    都是一個特點,前端控制器模式
    記住:前端控制器(核心的控制器)
    Struts2開啟前端的控制器就是過濾器

環境準備
1、建立WEB專案,編寫JSP的頁面,編寫超連結,點選超連結傳送請求,請求伺服器,讓伺服器的方法執行
2、下載Struts2的開發包
    http://struts/apache/org 官網
3、解壓struts-2.x.x-all.zip
    解壓後會有包和一些檔案
        apps --Struts2框架提供一些應用
        libs --Struts2框架開發的jar包
        docs --Struts2框架開發文件
        src  --Struts2框架原始碼
4、引入需要開發的jar包
    Struts2框架的開發jar包非常多,但是不是所有都必須要引入,有一些必須要匯入的jar包,這些jar包可以在Struts2框架提供的應用中找到
    apps-> struts2-blank[空的模版].war war和zip的壓縮格式是一樣的,所以可以修改後綴名後解壓
    開啟應用後 WEB-INF/lib目錄下的所有jar包

5、配置Sturts2的前端控制器。必須要做,是Struts2核心的控制器
    Struts2的前端控制器就是一個過濾器,需要在web.xml中進行配置
    <!-- 配置前端控制器 在伺服器啟動時-->
<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>

Action類是動作類,是Struts2處理請求,封裝資料,響應頁面的核心控制器,需要自己寫

Struts2配置檔案
1、配置檔名稱是struts.xml(必須是)
2、在src下引入struts.xml配置檔案(路徑必須在src的目錄下)

Struts2執行的流程
1、執行的流程
    編寫頁面,點選超連結,請求提交到伺服器端
    請求會先經過Struts2的核心過濾器(StrutsPrepareAndExecuteFilter)
        過濾器的功能是完成了一部分程式碼功能
        一系列的攔截器執行了,進行了處理工作
        可以在struts-default.xml配置檔案中看到很多攔截器,可以通過斷點看
        攔截器執行完成後,會根據struts.xml的配置檔案找到請求路徑,找到具體的類,通過反射的方式讓方法執行
2、總結
    JSP頁面->StrutsPrepareAndExecuteFilter過濾器->執行一系列攔截器->執行到目標Action->返回字串->結果頁面(result)->頁面跳轉

struts.xml配置檔案的提示
1、struts.xml配置檔案 複製http://struts.apache.org/dtds/struts-2.3.dtd 沒有雙引號

2、window->首選項->搜尋xml->選擇xml Catalog
3、選擇新增按鈕
    key type 要選擇URI
    key的位置把剛才複製的路徑拷貝進去,http://struts.apache.org/dtds/struts-2.3.dtd 
    Location要在本地能找到struts2-2.3.dtd的檔案,點選File System 找到

4、如果想檢視原始碼
    選擇struts-2.3.24-all.zip



框架配置檔案載入的順序
1、Struts2框架的核心是StrutsPrepareAndExecuteFilter過濾器,該過濾器有2個功能
    Prepare     預處理,載入核心的配置檔案
    Execute     執行,讓部分攔截器執行

2、StrutsPrepareAndExecuteFilter過濾器會載入什麼配置檔案
    通過原始碼可以看到具體載入的配置檔案和載入配置檔案的順序
        init_DefaultProperties();               載入org/apache/struts/default.properties
        init_TraditionalXmlConfiguration()      載入struts-default.xml,struts-plugin.xml,struts.xml
        init_LegenctStrutsProperties();         載入自定義的struts.propertis
        init_CustomConfigurationProviders();    載入使用者自定義配置提供者
        init_FilterInitParameters();            載入web.xml

3、重點配置檔案
    default.properties      在org/apache/struts2/目錄下,代表的是配置的是的Struts2的常量的值
    struts-default.xml      在Struts2的核心包下,代表的是Struts2核心功能的配置(Bean、攔截器、結果型別等)
    struts.xml      重點中的重點配置,代表WEB應用的預設配置,在工作中,基本就配置這個(可以配置常量)
    web.xml         配置前端控制器(可以配置常量)

    前3個配置檔案是struts2框架的預設配置,基本不用修改
    後3個配置檔案可以允許自己修改struts2的常量,但是有個特點:後加載的配置檔案修改的常量的值,會覆蓋掉前面修改的常量的值

4、總結
    先載入default.propertis檔案,在org/apache/struts2/default.properties檔案,都是常量
    又載入struts-default.xml配置檔案,在核心的jar包最下方,struts2框架的核心功能都是在該配置檔案中配置的
    再載入struts.xml的配置檔案,在src目錄下,代表使用者自己配置的配置檔案
    最後載入web.xml的配置檔案

    後加載的配置檔案會覆蓋掉之前載入的配置檔案(這些配置檔案中可以配置常量)        

5、問題
    哪些配置檔案中可以配置常量
        default.properties      預設值,不能修改
        struts.xml              可以配置,開發中基本都是在該配置檔案中配置常量
        struts.default.xml      可以配置,基本不會在該配置檔案中配置
        web.xml                 可以配置,基本不會在該配置檔案中配置

    後加載的配置檔案會覆蓋掉之前載入的配置

struts.xml檔案的配置
1、<package>標籤,如果要配置<Action>的標籤,那麼必須要先配置<package>標籤,代表包的概念
    包含的屬性
        name                包的名稱,要求是唯一的,管理action配置
        extends             繼承,可以繼承其他的包,只要繼承了,那麼該包就包含了其他包的功能,一般都是繼承struts-default
        namespace           名稱空間,一般與<action>標籤中的name屬性共同決定訪問路徑(怎麼來訪問action)常見的配置
            namespace="/"       根名稱空間
            namespace="/aaa"    帶有名稱的名稱空間
        abstract            抽象的,這個屬性基本很少使用,值如果是true,那麼編寫的包是被繼承的
2、<action>標籤
    代表配置action類,包含的屬性
        name        和<package>標籤的namespace屬性一起來決定訪問路徑的
        class       配置Action類的全路徑(預設值是ActionSupport類)
        method      Action類中的執行方法,如果不指定,預設值是execute
3、<result>標籤 可以多個標籤
    action類中方法執行,返回的結果跳轉的頁面
        name        結果頁面邏輯檢視名稱
        type        結果型別(預設值為轉發,也可以設定為其他的值)

Struts2配置常量
1、可以在Struts2框架中的哪些檔案中配置常量
    struts.xml(必須要掌握)
        <constant nemw="key" value="value"></constant>
    web.xml
        在StrutsPrepareAndExecuteFilter配置檔案中配置初始化引數
    後加載的配置檔案的常量會覆蓋掉之前載入的常量

2、大概的瞭解的常量
    struts.i18n.encoding=UTF-8              指定預設編碼集,作用於HttpServletRequest的setCharacterEncoding方法
    struts.action.extension=action          該屬性指定需要Struts2處理的請求字尾,該屬性的預設值是action,即所有匹配*.action的請求都由Struts2處理,
        如果使用者需要指定多個請求字尾,則多個字尾之間以英文逗號(,)隔開 ,,表示沒有後綴的檔案
    struts.serve.static.browserCache=true       設定瀏覽器是否快取靜態內容。預設值為true(生成環境下用),開發最好關閉
    struts.configuration.xml.reload=false   當struts的配置檔案修改後,系統是否自動重新載入該檔案,預設值為false(生產環境下用)
    struts.devMode=false                    開發模式下用,可以打印出更詳細的錯誤資訊

指定多個struts配置檔案
1、隨著應用規模增加Action的數量也會大量增加,導致struts.xml配置檔案非常臃腫
    為了避免struts.xml檔案過於龐大,提高可讀性,可以把struts.xml檔案分成多個然後在struts.xml檔案中包含其他配置檔案

2、在<package>標籤中,使用<include>標籤來引入其他的struct_xx.xml的配置檔案
    <struts>
        <include file="struts_part1.xml"/>
        <include file="struts_part2.xml"/>
    </struts>
3、<include file="my/demo2/struts-part1.xml"/>

Action類的三種寫法
1、三種寫法
    Action類就是一個POJO類
        POJO(Plain Ordinary Java Object)簡單的Java物件,簡單說就是沒有繼承某某個類,沒有實現介面就是POJO類
    Action類可以實現Action介面
        Action介面中定義了5個常量,5個常量的值對應的是5個邏輯檢視跳轉頁面(跳轉的頁面需要自己來配置)
            還定義了一個方法,execute方法
        需要掌握5個邏輯檢視的常量
            success         成功
            input           使用者資料表單校驗,如果校驗失敗,跳轉Input檢視
            login           登入
            error           錯誤
            none            頁面不轉向

    Action類可以繼承ActionSupport類(使用的最多)
        設定錯誤資訊  

Action的訪問
1、通過<action>標籤中的method屬性,訪問到Action中具體的方法
    傳統的配置方式,配置更清晰更好理解,但是擴充套件需要修改配置檔案等
    頁面
    <a href="${pageContext.request.contextPath }/saveCust.action">儲存客戶</a>
    <a href="${pageContext.request.contextPath }/delCust.action">刪除客戶</a>
    配置檔案
    <package name="demo2" namespace="/" extends="struts-default">
        <action name="saveCust" class="my.action2.CustomerAction" method="save"/>
        <action name="delCust" class="my.action2.CustomerAction" method="delete"/>
    </package>
    Action程式碼
    //儲存客戶
    public String save() {
        System.out.println("儲存客戶.");
        return NONE;
    }
    //刪除客戶
    public String delete() {
        System.out.println("刪除客戶");
        return NONE;
    }       
2、萬用字元的訪問方式(訪問的路徑和方法的名稱必須要有某種練習) 萬用字元就是*代表任意字元
    使用萬用字元的方式可以簡化配置檔案的程式碼縮寫,而且擴充套件和維護比較容易
    頁面程式碼
        <a href="${pageContext.request.contextPath }/linkman_save.action">儲存聯絡人</a>
        <a href="${pageContext.request.contextPath }/linkman_delete.action">刪除聯絡人</a>
    配置檔案
        <!-- 萬用字元的方式 取出第一個星的值和Action類中進行匹配-->
         <action name="linkman_*" class="my.action2.LinkmanAction" method="{1}">
            <result name="saveOk">/demo1/suc.jsp</result>
            <result name="delOk">/demo1/suc.jsp</result>
         </action>
    Action程式碼
        //儲存聯絡人
        public String save() {
            System.out.println("儲存聯絡人.");
            return "saveOk";
        }
        //刪除聯絡人
        public String delete() {
            System.out.println("刪除聯絡人");
            return "delOk";
        }
    在JSP頁面傳送請求,http://localhost:8080/day06/linkman_save.action配置檔案中的linkman_*可以匹配該請求,*就相當於變成了add,method屬性的值使用{1}來代替,{1}就表示的是第一個*號的位置。所以method的值就等於了add,那麼就找到Action類中的add方法,那麼add方法就執行了

3、動態方法訪問的方式(有的開發也會用)
    如果想完成動態方法訪問的方式,需要開啟一個常量,struts.enable.DynamicMethodInvocation=false,把值設定成true
        不同的Struts2框架的版本,該常量的值不一定是true或者false,需要自己來檢視,如果是false們需要自己來開啟
    在struts.xml中開啟該常量
        <constant name="struts.enable.DynamicMethodInvocation" value="true"/>

    頁面的程式碼
        <a href="${pageContext.request.contextPath }/user!save.action">儲存小弟</a>
        <a href="${pageContext.request.contextPath }/user!delete.action">刪除小弟</a>
    配置檔案
        <action name="user" class="my.action2.UserAction" ></action>
    Action的類
        public String save() {
        System.out.println("儲存客戶.");
        return NONE;
        }
        //刪除客戶
        public String delete() {
            System.out.println("刪除客戶");
            return NONE;
        }