攔截器 & Structs國(guó)際化 & Ognl

攔截器

  • 攔截器概述 :

    • 基本概念 : Intercetor, 即為攔截器。
      1. 在Struts2中把每一個(gè)功能都用一個(gè)個(gè)的攔截器實(shí)現(xiàn);用戶想用struts的哪個(gè)功能的時(shí)候,可以自由組裝使用。
      2. Struts2中為了方法用戶對(duì)攔截器的引用, 提供了攔截器棧的定義, 里面可以包含多個(gè)攔截器。文件夾(文件, 文件2) 攔截器棧(攔截器, 攔截器2)
      3. Struts2中如果用戶沒(méi)有指定執(zhí)行哪些攔截器, struts2有一個(gè)默認(rèn)執(zhí)行的棧, defaultStack; 一旦如果用戶有指定執(zhí)行哪些攔截器, 默認(rèn)的攔截器棧就不會(huì)被執(zhí)行攔截器的設(shè)計(jì), 就是基于組件設(shè)計(jì)的應(yīng)用!
  • 攔截器配置舉例 : struts-default.xml文件中,定義了struts提供的所有攔截器

    // 1. 定義攔截器以及攔截器棧
<interceptors>
    // 1.1 攔截器定義
    <interceptor name="" class="" /> 
    // 1.2 攔截器棧的定義
    <interceptor-stack name="defaultStack">
    引用了上面攔截器(1.1)
    </interceptor-stack>
</interceptors>
    // 2. 默認(rèn)執(zhí)行的攔截器(棧)
<default-interceptor-ref name="defaultStack"/>
  • 攔截器API :

    • Interceptor 攔截器接口
    • AbstractInterceptor : 攔截器默認(rèn)實(shí)現(xiàn)的抽象類; 一般用戶只需要繼承此類即可繼續(xù)攔截器開(kāi)發(fā)
    • ActionInvocation : 攔截器的執(zhí)行狀態(tài), 調(diào)用下一個(gè)攔截器或Action
  • 自定義一個(gè)攔截器案例

    • 步驟:
      1. 寫(xiě)攔截器類 (看生命周期)
      2. 配置
      3. 代碼示例
// 自定義攔截器
public class HelloInterceptor implements Interceptor{
    // 啟動(dòng)時(shí)候執(zhí)行
    public HelloInterceptor(){
        System.out.println("創(chuàng)建了攔截器對(duì)象");
    }
    // 啟動(dòng)時(shí)候執(zhí)行
    @Override
    public void init() {
        System.out.println("執(zhí)行了攔截器的初始化方法");
    }
    // 攔截器業(yè)務(wù)處理方法 (在訪問(wèn)action時(shí)候執(zhí)行? 在execute之前執(zhí)行?)
    @Override
    public String intercept(ActionInvocation invocation) throws Exception {
        System.out.println("2. 攔截器,業(yè)務(wù)處理-開(kāi)始");
        // 調(diào)用下一個(gè)攔截器或執(zhí)行Action  (相當(dāng)于chain.doFilter(..)
        // 獲取的是: execute方法的返回值
        String resultFlag = invocation.invoke();
        System.out.println("4. 攔截器,業(yè)務(wù)處理-結(jié)束");
        return resultFlag;
    }
    @Override
    public void destroy() {
        System.out.println("銷毀....");
    }
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
    "http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
    <package name="hello" extends="struts-default">

        <!-- 【攔截器配置】 -->
        <interceptors>
            <!-- 配置用戶自定義的攔截器 -->
            <interceptor name="helloInterceptor" class="cn.itcast.a_interceptor.HelloInterceptor"></interceptor>
            <!-- 自定義一個(gè)棧: 要引用默認(rèn)棧、自定義的攔截器 -->
            <interceptor-stack name="helloStack">
                <!-- 引用默認(rèn)棧 (一定要放到第一行)-->
                <interceptor-ref name="defaultStack"></interceptor-ref>
                <!-- 引用自定義攔截器 -->
                <interceptor-ref name="helloInterceptor"></interceptor-ref>
            </interceptor-stack>
        </interceptors>
        
        <!-- 【執(zhí)行攔截器】 -->
        <default-interceptor-ref name="helloStack"></default-interceptor-ref>
    
        <!-- Action配置 -->
        <action name="hello" class="cn.itcast.a_interceptor.HelloAction">
            <result name="success"></result>
        </action>
    </package>
</struts>
  • 攔截器執(zhí)行流程

    • 啟動(dòng) : 創(chuàng)建所有攔截器、執(zhí)行init()
    • 訪問(wèn):
      • 先創(chuàng)建Action,
      • 再執(zhí)行攔截器,
      • 最后 : 攔截器放行,執(zhí)行execute();
  • 攔截器案例

    • 需求:登陸后,顯示列表!
    • 案例準(zhǔn)備:
      • Struts jar文件
      • DbUtils組件
      • 數(shù)據(jù)庫(kù)連接池/ 驅(qū)動(dòng)包
    • 代碼
      • login.jsp :
<body>
     <form method="post" action="${pageContext.request.contextPath }/user_login.action">
        用戶名:<input type="text" name="admin.userName"><br/>
        密碼:<input type="text" name="admin.pwd"><br/>
        <input type="submit" value="登陸"><br/>
     </form>
  </body>
- UserAction.java : 
public class UserAction extends ActionSupport {
    // ---------1. 封裝請(qǐng)求數(shù)據(jù)-----------
    private Admin admin;
    public Admin getAdmin() {
        return admin;
    }
    public void setAdmin(Admin admin) {
        this.admin = admin;
    }
    // ---------2. 調(diào)用的Service-----------
    private AdminService adminService = new AdminService();
    // 登陸
    public String login() {
        try {
            Admin userInfo = adminService.login(admin);
            // 判斷
            if (userInfo == null){
                // 登陸失敗
                return "input";
            }
            // 登陸成功:數(shù)據(jù)保存在session中
            ActionContext.getContext().getSession().put("userInfo", userInfo);
            // 登陸成功
            return "loginSuccess";
        } catch (Exception e) {
            return ERROR;
        }
    }
    // 列表
    public String list() {
        try {
            // 查詢?nèi)?            List<Admin> list = adminService.getAll();
            // 保存到request
            ActionContext.getContext().getContextMap().put("listAdmin", list);
            return "list";
        } catch (Exception e) {
            return ERROR;
        }
    }
    public String add() {
        return null;
    }   
}
- list.jsp : 
<body>
    <h1>歡迎你,${userInfo.userName }</h1>
    <table align="center" border="1">
        <tr>
            <td>序號(hào)</td>
            <td>編號(hào)</td>
            <td>用戶名</td>
            <td>密碼</td>
        </tr>
        <%--@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" --%>
        <!-- 用struts標(biāo)簽迭代數(shù)據(jù) -->
        <%@taglib uri="/struts-tags" prefix="s" %>
        <s:iterator var="admin" value="#request.listAdmin" status="st">
            <tr>
                <td>
                    <s:property value="#st.count"/>
                </td>
                <td>
                    <s:property value="#admin.id"/>
                </td>
                <td>
                    <s:property value="#admin.userName"/>
                </td>
                <td>
                    <s:property value="#admin.pwd"/>
                </td>
            </tr>
        </s:iterator>
  
    </table>
  </body>
- 自定義攔截器
public class UserCheckInterceptor extends AbstractInterceptor{
    /**
     * 攔截器業(yè)務(wù)處理方法
     */
    public String intercept(ActionInvocation invocation) throws Exception {
        // 拿到當(dāng)前執(zhí)行的方法名:判斷,只有當(dāng)前方法名不是login,就進(jìn)行驗(yàn)證
        
        // 獲取ActionContext對(duì)象
        ActionContext ac = invocation.getInvocationContext();
        
        // 獲取action的代理對(duì)象
         ActionProxy proxy = invocation.getProxy();
         // 獲取當(dāng)前執(zhí)行的方法名
         String methodName = proxy.getMethod();
         // 判斷
         if (!"login".equals(methodName)) {
             // 先獲取當(dāng)前登陸的用戶
             Object obj = ac.getSession().get("userInfo");
             if (obj == null) {
                 // 沒(méi)有登陸
                 return "input";
             } else {
                 // 當(dāng)前用戶有登陸
                 return invocation.invoke();
             }
         } else {
             // 說(shuō)明當(dāng)前用戶正在登陸
             return invocation.invoke();
         }
    }
}
- 配置攔截器
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
    "http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
    <package name="user" extends="struts-default">
    
        <!-- 【攔截器配置】 -->
        <interceptors>
            <interceptor name="loginCheck" class="cn.itcast.interceptor.UserCheckInterceptor"></interceptor>
            <interceptor-stack name="myStack">
                <interceptor-ref name="defaultStack"></interceptor-ref>
                <interceptor-ref name="loginCheck"></interceptor-ref>
            </interceptor-stack>
        </interceptors>
        <!-- 【執(zhí)行攔截器:第一種寫(xiě)法: 當(dāng)前包下所有的acntion都執(zhí)行myStack棧】
        <default-interceptor-ref name="myStack"></default-interceptor-ref>
         -->
    
        <!-- 全局配置 -->
        <global-results>
            <result name="error">/error.jsp</result>
        </global-results>
        
        <action name="user_*" class="cn.itcast.action.UserAction" method="{1}">
            
            <!--第二種寫(xiě)法: 只是在這一個(gè)Action中執(zhí)行myStack棧 
            <interceptor-ref name="defaultStackt"></interceptor-ref>
            <interceptor-ref name="loginCheck"></interceptor-ref>
            -->
            
            <!-- 第三種寫(xiě)法:執(zhí)行用戶棧(與第二種寫(xiě)法一樣, 只在當(dāng)前aciton中執(zhí)行自定義棧) -->
            <interceptor-ref name="myStack"></interceptor-ref>
            
            <!-- 1. 登陸失敗 -->
            <result name="input">/login.jsp</result>
            
            <!-- 2. 登陸成功 -->
            <result name="loginSuccess" type="redirectAction">user_list</result>
            
            <!-- 3. 列表展示 -->
            <result name="list">/WEB-INF/list.jsp</result>
        </action>
    </package>
</struts>

Structs國(guó)際化

  • Struts2中國(guó)際化:
    1. 寫(xiě)資源文件 (同servlet)
    2. 讀資源文件
    • 程序:ResourceBundle (同servlet)
    • JSP:
      1)jstl標(biāo)簽(同servlet)
      2)struts標(biāo)簽獲取資源文件內(nèi)容
  • 具體步驟 :
    1. 寫(xiě)資源文件 :
    • Msg.properties : 默認(rèn)的語(yǔ)言環(huán)境, 找不到配置就找它
    • Msg_en_US.properties : 美國(guó)
    1. 加載 : <constant name="struts.custom.i18n.resources" value="cn.itcast.config.msg"></constant>
    2. 使用 : 標(biāo)簽name值直接寫(xiě)配置文件中的key : <s:text name="title"></s:text>
    • 另外一點(diǎn),(推薦)加載資源文件通過(guò)常量加載還可以在頁(yè)面加載, 這樣用:
<s:i18n name="cn.itcast.config.msg">
    <s:text>  標(biāo)簽必須放到標(biāo)簽體中 </s:text>
</s:i18n>

Ognl表達(dá)式語(yǔ)言

  • 概述 : OGNL是Object Graphic Navigation Language(對(duì)象圖導(dǎo)航語(yǔ)言)的縮寫(xiě), 它是一個(gè)開(kāi)源項(xiàng)目, Struts2框架使用OGNL作為默認(rèn)的表達(dá)式語(yǔ)言

    • OGNL優(yōu)勢(shì)
      1、支持對(duì)象方法調(diào)用,如xxx.doSomeSpecial();
      2、支持類靜態(tài)的方法調(diào)用和值訪問(wèn),表達(dá)式的格式:
      @[類全名(包括包路徑)]@[方法名 | 值名],例如:
      @java.lang.String@format('foo %s', 'bar')
      或@tutorial.MyConstant@APP_NAME;
      3、支持賦值操作和表達(dá)式串聯(lián),如price=100, discount=0.8, calculatePrice(),這個(gè)表達(dá)式會(huì)返回80;
      4、訪問(wèn)OGNL上下文(OGNL context)和ActionContext
      5、操作集合對(duì)象
    • 總結(jié) : OGNL 有一個(gè)上下文(Context)概念,說(shuō)白了上下文就是一個(gè)MAP結(jié)構(gòu), 它實(shí)現(xiàn)了 java.utils.Map 的接口。 OgnlContext對(duì)象
    • 分析:Struts框架默認(rèn)就支持Ognl表達(dá)式語(yǔ)言(struts必須引用的包:ognl.jar)
    • 作用 : 頁(yè)面取值用
      1> El表達(dá)式語(yǔ)言 : jsp頁(yè)面取值的標(biāo)準(zhǔn)。(默認(rèn)直接可以使用) (應(yīng)用范圍更廣)
      2> Ognl表達(dá)式語(yǔ)言 : struts標(biāo)簽?zāi)J(rèn)支持的表達(dá)式語(yǔ)言。必須配置struts標(biāo)簽用, 不能離開(kāi)struts標(biāo)簽直接用
  • OgnlContext對(duì)象 : OgnlContext對(duì)象是ognl表達(dá)式語(yǔ)言的核心。

    • 源碼類:public class OgnlContext extends Object implements Map{..}硬編碼方式,了解OgnlContext對(duì)象:

// OgnlContext用法
public class OgnlDemo1 {

    /**
     * 1. Ognl表達(dá)式語(yǔ)言取值,取非根元素的值,必須用#號(hào)
     * @throws Exception
     */
    @Test
    public void testOgnl() throws Exception {
        // 創(chuàng)建一個(gè)Ognl上下文對(duì)象
        OgnlContext context = new OgnlContext();
        // 放入數(shù)據(jù)
        User user = new User();
        user.setId(100);
        user.setName("Jack");
        // 【往非根元素放入數(shù)據(jù), 取值的時(shí)候表達(dá)式要用"#"】
        context.put("user", user);
        
        // 獲取數(shù)據(jù)(map)
        // 先構(gòu)建一個(gè)Ognl表達(dá)式, 再解析表達(dá)式
        Object ognl = Ognl.parseExpression("#user.name");
        Object value = Ognl.getValue(ognl, context, context.getRoot());
        
        System.out.println(value);
    }
    
    /**
     * 2. Ognl表達(dá)式語(yǔ)言語(yǔ)言取值,取根元素的值,不用帶#號(hào)
     * @throws Exception
     */
    @Test
    public void testOgn2() throws Exception {
        // 創(chuàng)建一個(gè)Ognl上下文對(duì)象
        OgnlContext context = new OgnlContext();
        // 放入數(shù)據(jù)
        User user = new User();
        user.setId(100);
        user.setName("Jack");
        // 【往根元素放入數(shù)據(jù)】
        context.setRoot(user);
        
        // 獲取數(shù)據(jù)(map)
        // 先構(gòu)建一個(gè)Ognl表達(dá)式, 再解析表達(dá)式
        Object ognl = Ognl.parseExpression("address.province");
        Object value = Ognl.getValue(ognl, context, context.getRoot());
        
        System.out.println(value);
    }
    
    /**
     * 3.Ognl對(duì) 靜態(tài)方法調(diào)用的支持
     * @throws Exception
     */
    @Test
    public void testOgn3() throws Exception {
        // 創(chuàng)建一個(gè)Ognl上下文對(duì)象
        OgnlContext context = new OgnlContext();
        
        // Ognl表單式語(yǔ)言,調(diào)用類的靜態(tài)方法
        //Object ognl = Ognl.parseExpression("@Math@floor(10.9)");
        // 由于Math類在開(kāi)發(fā)中比較常用,所以也可以這樣寫(xiě)
        Object ognl = Ognl.parseExpression("@@floor(10.9)");
        Object value = Ognl.getValue(ognl, context, context.getRoot());
        System.out.println(value);
    }
}
  • ValueStack(即值棧對(duì)象) :
    • 值棧對(duì)象:是整個(gè)struts數(shù)據(jù)存儲(chǔ)的核心,或者叫中轉(zhuǎn)站。用戶每次訪問(wèn)struts的action,都會(huì)創(chuàng)建一個(gè)Action對(duì)象、值棧對(duì)象、ActionContext對(duì)象; 然后把Action對(duì)象放入值棧中; 最后再把值棧對(duì)象放入request中,傳入jsp頁(yè)面(key: struts.valueStack); 開(kāi)發(fā)者只需要通過(guò)ActionContext對(duì)象就可以訪問(wèn)struts的其他的關(guān)鍵對(duì)象(ActionContext是給開(kāi)發(fā)者用的,便于學(xué)習(xí)與使用)
    • 問(wèn)題 : OgnlContext與ValueStack對(duì)象的關(guān)系?
  • Struts標(biāo)簽 : Struts標(biāo)簽取值,就使用了Ognl表達(dá)式語(yǔ)言
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容