Struct2

加載流程

StrutsPrepareAndExecuteFilter Struts2中的核心類,有兩個功能:預(yù)處理執(zhí)行

  • 預(yù)處理

    • 配置文件加載順序

      • struts.properties ---- 配置常量name = value

      • struts.xml ---- 配置Action及常量<constant name="" value="">

        使用include進行分模塊開發(fā),在struts.xml中包含其他配置文件,被包含的文件都是標(biāo)準(zhǔn)的struts配置文件

        <include file="struts.xml"/>
        <include file="com/sd/struts.xml"/>
        
      • web.xml ---- 配置核心過濾器及常量init-param

        以上三個配置文件均可添加常量桩撮,后加載的配置文件中的常量值會將先加載配置文件中的常量值覆蓋

配置常量

  • 國際化,解決post提交亂碼

    <constant name="struts.i18n.encoding

  • 指定訪問action的后綴名邀窃,以下指定后綴為action或不進行配置

    <constant name="struts.action.extension" value="action,,"/>

  • 指定struts2是否以開發(fā)模式運行

    • 熱加載主配置
    • 提供更多的錯誤信息輸出,方便開發(fā)時調(diào)試

    <constant name="struts.devMode" value="true"/>

默認配置

<struts>
    <package name="demo" extends="struts-default" namespace="/">
        <!-- 如果訪問路徑404時嘱能,跳轉(zhuǎn)到default-action-ref指定action -->
        <default-action-ref name="demo1"/>
        <!-- method 默認為execute()-->
        <!-- result name 默認為success-->
        <!-- result type 默認為dispatcher-->
        <!-- class 默認為com.opensymphony.xwork2.ActionSupport -->
        <action name="demo1">
            <result name="*" type="dispatcher">/welcome.jsp</result>
        </action>
    </package>
</struts>

Action編寫方式

  • 普通POJO類

    定義業(yè)務(wù)方法撬呢,默認為execute()方法public String execute()伦吠,也可實現(xiàn)其他方法(需要在struts.xml中定義,method參數(shù)執(zhí)行定義的方法)

  • 實現(xiàn)Action接口,定義了五個字符串常量

    SUCCESS,NONE,ERROR,INPUT,LOGIN

  • 繼承ActionSupport類

    提供了許多默認方法魂拦,包括獲取國際化信息的方法讨勤,數(shù)據(jù)校驗方法,默認的用戶請求方法等

Action動態(tài)方法調(diào)用

  • 通配符配置

    • 配置struts.xml
    <struts>
        <package name="demo" extends="struts-default" namespace="/">
            <global-allowed-methods>regex:.*</global-allowed-methods>
            <action name="demo1_*" class="com.sd.action.Action1" method="{1}">
                <result name="*">/welcome.jsp</result>
            </action>
        </package>
    </struts>
    

    name屬性中的*代表任意字符晨另,method中的{1}代表name屬性中出現(xiàn)的第一個 * 所代替的字符

    • 定義

      public String add() {
          System.out.println("增加");
          return SUCCESS;
      }
      
      • 引用

        <h4><a href="${pageContext.request.contextPath}/demo1_add">示例一:增加</a></h4>
        
  • 動態(tài)訪問(使用!來匹配方法,不符合SEO引擎優(yōu)化)

    • 開啟動態(tài)訪問struts.xml

      <struts>
          <constant name="struts.enable.DynamicMethodInvocation" value="true"/>
          <package name="demo" extends="struts-default" namespace="/">
              <global-allowed-methods>regex:.*</global-allowed-methods>
              <action name="demo1" class="com.sd.action.Action1">
                  <result name="*">/welcome.jsp</result>
              </action>
          </package>
      </struts>
      
  • 定義

    public String add() {
      System.out.println("增加");
      return SUCCESS;
    }
    
  • 引用

    <h4><a href="${pageContext.request.contextPath}/demo1!add">示例一:增加</a></h4>
    

Structs2訪問servlet API

  • ActionContext

    • HttpServletRequest(獲取,設(shè)置request參數(shù))

      void put(String key,Object value)

      Object get(String key)

      HttpParameters getParameters()

    • Application

      void setApplication(Map<String,Object> application)

      Map<String,Object> getApplication()

    • Session

      void setSession(Map<String,Object> session)

      Map<String,Object> getSession()

    • ActionContext

      static ActionContext getContext();//獲取當(dāng)前線程的ActionContext 對象

  • ServeletActionContext

  • 通過特定接口訪問

    • ServletRequestAware:實現(xiàn)該接口的Action可以直接訪問web應(yīng)用的HttpServletRequest實例
    • ServletResponseAware:實現(xiàn)該接口Action可以直接訪問web應(yīng)用的HttpServletResponse實例
    • SessionAware:實現(xiàn)該接口Action可以直接訪問web應(yīng)用的HttpSession實例
    • SevletContextAware:實現(xiàn)該接口Action可以直接訪問web應(yīng)用的SevletContext實例

結(jié)果頁面配置

  • 跳轉(zhuǎn)方式
//轉(zhuǎn)發(fā)到Action
<result name="*" type="chain">
    <param name="actionName">demo1</param>
    <param name="namespace">/</param>
</result>   
//轉(zhuǎn)發(fā)到JSP
<result name="*" type="dispatcher">/welcome.jsp</result>
//重定向到JSP
<result name="*" type="redirect">/welcome.jsp</result>
//重定向到Action
<result name="*" type="redirect">
    <param name="actionName">demo1</param>
    <param name="namespace">/</param>
</result>   
  • 全局結(jié)果頁面配置

    在這個包下所有返回相同字符串的值谱姓,都可以向這個頁面進行跳轉(zhuǎn)

    <global-results>
        <result name="error">/welcome.jsp</result>
    </global-results>
    
  • 局部頁面配置

    某個Action中返回的字符串的值借尿,會向這個頁面跳轉(zhuǎn)

    <action name="demo1">
        <result name="*" type="dispatcher">/welcome.jsp</result>
    </action>
    

獲得參數(shù)的方式

  • 屬性驅(qū)動

    • 準(zhǔn)備與參數(shù)鍵名稱相同的屬性
    • 自動類型轉(zhuǎn)換,只能轉(zhuǎn)換8大基本數(shù)據(jù)類型及對應(yīng)包裝類
    • 支持特定類型字符串轉(zhuǎn)化為Date,例如yyyy-MM-dd
  • 對象驅(qū)動

  • 模型驅(qū)動(實現(xiàn)ModelDriven接口)

    //此處必須手動new 對象屉来,否則會報NPE
    private User userhaha=new User();
    @Override
    public User getModel() {
        return userhaha;
    }
    
  • 集合類型參數(shù)封裝

    • List

      • 定義

        private List<User> userList;
        public List<User> getUserList() {
                return userList;
        }
        
        public void setUserList(List<User> userList) {
          this.userList = userList;
        }
        
      • jsp配置

        <form action="${pageContext.request.contextPath}/parm" method="post">
            姓名:<input type="text" name="userList.name"></br>
            年齡:<input type="text" name="userList.age"></br>//userList默認為userList[0]
            生日:<input type="text" name="userList[0].birthday">
            </br>
            </br>
            </br>
            姓名:<input type="text" name="userList[1].name"></br>
            年齡:<input type="text" name="userList[1].age"></br>
            生日:<input type="text" name="userList[1].birthday">
            <input type="submit" value="提交">
        </form>
        
    • Map

      • 定義

        private Map<String,User> users;
        public Map<String, User> getUsers() {
            return users;
        }
        public void setUsers(Map<String, User> users) {
            this.users = users;
        }
        
      • 配置

        <form action="${pageContext.request.contextPath}/param" method="post">
            姓名:<input type="text" name="users['one'].name"><br>
            年齡:<input type="text" name="users['one'].age"><br>
            生日:<input type="text" name="users['one'].birthday"><br>
        愛好:
            跑步:<input type="checkbox" name="users['one'].love" value="run"><br>
            讀書:<input type="checkbox" name="users['one'].love" value="book"><br>
            寵物:<input type="checkbox" name="users['one'].love" value="pat"><br>
            聯(lián)系人1:<br>
            姓名:<input type="text" name="users['two'].name"><br>
            年齡:<input type="text" name="users['two'].age"><br>
            生日:<input type="text" name="users['two'].birthday"><br>
        <%--    聯(lián)系人2:<br>  
            姓名:<input type="text" name="users['two'].name"><br>
            年齡:<input type="text" name="users['two'].age"><br>
            生日:<input type="text" name="users['two'].birthday"><br>--%>
            <input type="submit" value="提交"><br>
        </form>
        //備注:同一個name值不能出現(xiàn)兩次及兩次以上
        

聲明式異常處理

根據(jù)<exception-mapping>出現(xiàn)的位置,異常映射分為兩種:

  • 局部異常映射:將<excepion-mapping>元素作為<action>元素的子元素配置;
  • 全局異常映射:將<exception-mapping>元素作為<global-exception-mappings>元素的子元素
<package name="demo" namespace="/" extends="struts-default">
    <global-results>
        <result name="sql">/index.jsp</result>
    </global-results>
    <global-exception-mappings>
        <exception-mapping result="sql" exception="java.sql.SQLException"/>
    </global-exception-mappings>
    <action name="testParams" class="com.ognl.Demo1Action">
        <exception-mapping result="sql" exception="java.sql.SQLException"/>
    </action>
</package>

全局異常映射對所有的 Action 類都有效,但局部異常映射僅對該異常映射所在的 Action 有效;

攔截器

  • 生命周期

    生命周期隨項目啟動創(chuàng)建路翻,隨項目關(guān)閉而銷毀

  • 自定義攔截器

    • 實現(xiàn)Interceptor接口

    • 繼承AbstractInterceptor類

    • 繼承MethodFilterInterceptor類(方法過濾攔截器)

      定制攔截器攔截方法(攔截哪些方法,哪些方法不攔截)

      @Override
      protected String doIntercept(ActionInvocation actionInvocation) throws Exception {
          /**
           * 攔截器放行茄靠,需要調(diào)用actionInvocation.invoke()方法,返回null即可茂契,邏輯視圖由Action處理
           * 攔截器不放行,不需要調(diào)用actionInvocation.invoke()方法,需要返回一個字符串作為邏輯視圖慨绳,
           *               系統(tǒng)會根據(jù)返回的字符串跳轉(zhuǎn)到對應(yīng)的視圖資源
           */
          //前處理
          actionInvocation.invoke();//放行
          //后處理
          return null;//返回邏輯視圖
      }
      
  • 配置攔截器

    • 注冊攔截器

    • 指定攔截器棧

    • 指定默認攔截器棧掉冶,定制方法是否攔截

      <interceptors>
          <!-- 注冊攔截器 -->
          <interceptor name="myInters" class="com.interceptor.MyInterceptor"/>
          <!-- 指定攔截器棧-->
          <interceptor-stack name="myStack">
              <!-- 引用定義攔截器 -->
              <interceptor-ref name="myInters">
                  <!-- 不能同時指定 -->
                  <!-- 指定方法不攔截 -->
                  <param name="excludeMethods">add,select</param>
                  <!-- 指定方法攔截 -->
                  <!-- <param name="includeMethods"></param> -->
              </interceptor-ref>
              <!-- 引用默認攔截器 -->
              <interceptor-ref name="defaultStack"/>
          </interceptor-stack>
      </interceptors>
      <!-- 指定默認的攔截器棧 -->
      <default-interceptor-ref name="myStack"/>
      

OGNL與Struts2的體現(xiàn)(ValueStack)

? 默認情況下,棧(CompoundRoot root)中放置當(dāng)前訪問的Action對象,提供push()pop()方法脐雪。Context部分就是ActionContext數(shù)據(jù)中心

  • 參數(shù)接受

    通過ognl來實現(xiàn)原生接受到的參數(shù)轉(zhuǎn)換成最終Action對象的參數(shù)獲取方法(以上三種)

    //獲取值棧
    ValueStack stack = ActionContext.getContext().getValueStack();
    stack.push(xxx);
    
  • 配置文件

    <struts>
        <package name="demo" namespace="/" extends="struts-default">
            <action name="testParams" class="com.ognl.Demo1Action">
                <result name="success" type="redirectAction">
                    <param name="namespace">/</param>
                    <param name="actionName">params</param>
                    <!-- 如果添加的參數(shù) struts "看不懂"厌小,則就會作為參數(shù),附加到重定向的路徑之后战秋,
                        如果參數(shù)是動態(tài)的璧亚,可以使用${ }包裹ognl表達式動態(tài)取值,取值的位置位于ognl
                        的值棧區(qū)脂信,即對應(yīng)的Action對象-->
                    <param name="name">${name}</param>
                </result>
            </action>
            <action name="params" class="com.ognl.Demo2Action">
                <result name="*">/index.jsp</result>
            </action>
        </package>
    </struts>
    
    public class Demo1Action extends ActionSupport{
        private String name="李雷與韓梅梅";
    
        @Override
        public String execute() throws Exception {
            return SUCCESS;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    }
    
    http://localhost:8080/params.action?name=李雷與韓梅梅
    
  • Struts2標(biāo)簽

    <%@ taglib prefix="s" uri="/struts-tags" %>

    • Debug

      <s:debug/>

    • 遍歷標(biāo)簽

      !-- 遍歷標(biāo)簽 -->
      <s:iterator value="#names"  status="st">
          <s:if test="#st.odd">
              <s:property value="#st.index"/><br/>
          </s:if>
          <s:property/><br/>
      </s:iterator>
      
      <s:iterator value="#names" var="name">
          <s:property value="#name"/><br/>
      </s:iterator>
      
      <s:iterator begin="1" end="10" status="1">
          <s:property/>
      </s:iterator>
      
      <br/>
      <s:if test="#names.size()==4">
          list 長度為4
      </s:if>
      <s:elseif test="#names.size()==5">
          list 長度為5
      </s:elseif>
      <s:else>
          list 長度不為4
      </s:else>
      
    • 屬性標(biāo)簽

      根據(jù)是否帶#決定是在ValueStack哪個部分取值

      <s:property value="hello"/><br/>
      <s:property value="hello.length()"/><br/>
      <s:debug/>
      

      ?

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末癣蟋,一起剝皮案震驚了整個濱河市透硝,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌疯搅,老刑警劉巖濒生,帶你破解...
    沈念sama閱讀 221,273評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異秉撇,居然都是意外死亡甜攀,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,349評論 3 398
  • 文/潘曉璐 我一進店門琐馆,熙熙樓的掌柜王于貴愁眉苦臉地迎上來规阀,“玉大人,你說我怎么就攤上這事瘦麸∷常” “怎么了?”我有些...
    開封第一講書人閱讀 167,709評論 0 360
  • 文/不壞的土叔 我叫張陵滋饲,是天一觀的道長厉碟。 經(jīng)常有香客問我,道長屠缭,這世上最難降的妖魔是什么箍鼓? 我笑而不...
    開封第一講書人閱讀 59,520評論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮呵曹,結(jié)果婚禮上款咖,老公的妹妹穿的比我還像新娘。我一直安慰自己奄喂,他們只是感情好铐殃,可當(dāng)我...
    茶點故事閱讀 68,515評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著跨新,像睡著了一般富腊。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上域帐,一...
    開封第一講書人閱讀 52,158評論 1 308
  • 那天赘被,我揣著相機與錄音,去河邊找鬼肖揣。 笑死帘腹,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的许饿。 我是一名探鬼主播阳欲,決...
    沈念sama閱讀 40,755評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了球化?” 一聲冷哼從身側(cè)響起秽晚,我...
    開封第一講書人閱讀 39,660評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎筒愚,沒想到半個月后赴蝇,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,203評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡巢掺,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,287評論 3 340
  • 正文 我和宋清朗相戀三年句伶,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片陆淀。...
    茶點故事閱讀 40,427評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡考余,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出轧苫,到底是詐尸還是另有隱情楚堤,我是刑警寧澤,帶...
    沈念sama閱讀 36,122評論 5 349
  • 正文 年R本政府宣布含懊,位于F島的核電站身冬,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏岔乔。R本人自食惡果不足惜酥筝,卻給世界環(huán)境...
    茶點故事閱讀 41,801評論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望雏门。 院中可真熱鬧嘿歌,春花似錦、人聲如沸剿配。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,272評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽呼胚。三九已至,卻和暖如春息裸,著一層夾襖步出監(jiān)牢的瞬間蝇更,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,393評論 1 272
  • 我被黑心中介騙來泰國打工呼盆, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留年扩,地道東北人。 一個月前我還...
    沈念sama閱讀 48,808評論 3 376
  • 正文 我出身青樓访圃,卻偏偏與公主長得像厨幻,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,440評論 2 359

推薦閱讀更多精彩內(nèi)容

  • 概述 什么是Struts2的框架Struts2是Struts1的下一代產(chǎn)品况脆,是在 struts1和WebWork的...
    inke閱讀 2,263評論 0 50
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理饭宾,服務(wù)發(fā)現(xiàn),斷路器格了,智...
    卡卡羅2017閱讀 134,693評論 18 139
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法看铆,類相關(guān)的語法,內(nèi)部類的語法盛末,繼承相關(guān)的語法弹惦,異常的語法,線程的語...
    子非魚_t_閱讀 31,660評論 18 399
  • 標(biāo)簽 如果要配置的標(biāo)簽悄但,那么必須要先配置標(biāo)簽棠隐,代表的包的概念。 包含的屬性 name包的名稱算墨,要求是唯一的宵荒,管理a...
    偷偷得路過閱讀 1,352評論 0 0
  • 1. 兒子的同學(xué)中挖藏,有很多都參加了各種課外補習(xí)班暑刃,這些班,有致力于提高語數(shù)英科文化課成績的膜眠,有培訓(xùn)琴棋書畫等各種特...
    萬伊刀閱讀 897評論 8 8