• JavaWeb学习:Struts2的拦截器


    一、概述

      Interceptor:拦截器,拦截Action的作用(Struts2框架核心功能都是依赖拦截器实现的)

        Filter:过滤器,过滤客户端向服务器发送的请求

        Interceptor:拦截器,拦截客户端对Action的访问,可以拦截Action中具体的方法

    二、Struts2的执行流程

      客户端向服务器发送一个Action的请求,执行核心过滤器(StrutsPrepareAndersonExecuteFilter)的doFilter()方法,执行executeAction()方法,执行dispatcher.serviceAction()创建一个Action代理,最终执行的是Action代理中的execute(),execute方法中调用ActionInvocation的invoke方法。在这个方法内部递归执行一组拦截器(完成部分功能),执行完所有拦截器,就会执行目标Action,根据Action的返回的结果进行页面跳转。

      

     三、自定义拦截器

      ①、搭建Struts2的环境(引入jar包、配置web.xml、编写Action、配置struts.xml)

      ②、编写拦截器类(类需要实现Interceptor接口或者继承AbstractInterceptor类)

    public class InterceptorDemo1 extends AbstractInterceptor {
    
        @Override
        public String intercept(ActionInvocation invocation) throws Exception {
        System.out.println("InterceptorDemo1执行");
        
        String result=invocation.invoke();
        
        System.out.println("InterceptorDemo1执行结束");
        return result;//invocation.invoke();
        }
    }

        继承AbstractInterceptor类只需要重写intercept()方法,而要实现Interceptor接口的,就需要多写一些方法

      ③、配置拦截器

        Ⅰ、直接引入自定义拦截器

        <package name="interceptorDemo" extends="struts-default" namespace="/">
            <!-- Ⅰ、定义拦截器 -->
            <interceptors>
                <interceptor name="interceptorDemo1" class="com.xxx.interceptor.InterceptorDemo1"/>
                <interceptor name="interceptorDemo2" class="com.xxx.interceptor.InterceptorDemo2"/>
            </interceptors>
            
            <action name="demo1" class="com.xxx.web.action.Demo1Action">
                <result>/demo1/index.jsp</result>
                <!-- Ⅱ、引入拦截器(一旦引入自定义拦截器,默认拦截栈中的拦截器就不会执行了,需要手动引入默认拦截器栈) -->
                <interceptor-ref name="defaultStack"></interceptor-ref>
                <interceptor-ref name="interceptorDemo1"></interceptor-ref>
                <interceptor-ref name="interceptorDemo2"></interceptor-ref>
            </action>
        </package>

        Ⅱ、通过拦截器栈的方式

        <package name="interceptorDemo" extends="struts-default" namespace="/">
            <!-- Ⅰ、定义拦截器 并定义拦截器栈-->
            <interceptors>
                <interceptor name="interceptorDemo1" class="com.xxx.interceptor.InterceptorDemo1"/>
                <interceptor name="interceptorDemo2" class="com.xxx.interceptor.InterceptorDemo2"/>
                
                <!-- Ⅱ、定义拦截器栈 (一旦引入自定义拦截器,默认拦截栈中的拦截器就不会执行了,需要手动引入默认拦截器栈) -->
                <interceptor-stack name="custStack">
                    <interceptor-ref name="defaultStack"></interceptor-ref>
                    <interceptor-ref name="interceptorDemo1"></interceptor-ref>
                    <interceptor-ref name="interceptorDemo2"></interceptor-ref>
                </interceptor-stack>
            </interceptors>
            
            <action name="demo1" class="com.xxx.web.action.Demo1Action">
                <result>/demo1/index.jsp</result>
                <!-- Ⅲ、引入自定义拦截器栈-->
                <interceptor-ref name="custStack"></interceptor-ref>
            </action>
        </package>

        注意:定义拦截器和拦截器栈都是在<package>节点下,而真正使用的拦截器的Action需要在对应的<action>节点中引入的拦截器

    四、拦截器中心思想

      就是AOP思想,在不修改程序代码的情况下,对程序进行扩展

      实例:权限拦截器

        ①、创建一个类型继承MethodFilterInterceptor类

    public class PrivilegeInterceptor extends MethodFilterInterceptor{
    
        @Override
        protected String doIntercept(ActionInvocation invocation) throws Exception {
        //判断session是否有用户数据
        User existUser=(User) ServletActionContext.getRequest().getSession().getAttribute("existUser");
        
        if(existUser==null) {
            //输出提示信息
            ActionSupport actionSupport= (ActionSupport) invocation.getAction();
            actionSupport.addActionError("没有登录,无法访问!");
            
            //回到登录页面
            return actionSupport.LOGIN;
        }
        //已经登录,继续执行
        return invocation.invoke();
        }
    }

      为什么要继承MethodFilterInterceptor?

        MethodFilterInterceptor中有两个属性:

          excludeMethods(拦截器不会拦截器的方法集合)

          includeMethods(拦截器需要拦截器的方法集合)

        protected Set<String> excludeMethods = Collections.emptySet();
        protected Set<String> includeMethods = Collections.emptySet();

      actionSupport.addActionError()方法,设置输出信息,jsp页面代码如下:

        <s:actionerror/>

        ②、配置拦截器

    <package name="crm" extends="struts-default" namespace="/">
            <!-- Ⅰ、定义拦截器 并定义拦截器栈-->
            <interceptors>
                <interceptor name="privilegeInterceptor" class="com.xxx.interceptor.PrivilegeInterceptor"/>
            </interceptors>
            
            <global-allowed-methods>regex:.*</global-allowed-methods>
            
            <!-- 每个action都需要login视图 -->
            <global-results>
                <result name="login">/login.jsp</result>
            </global-results>
            
            <action name="customer_*" class="com.xxx.web.action.CustomerAction" method="{1}">
                <result name="findSuccess">/jsp/customer/list.jsp</result>
                <result name="savaUI">/jsp/customer/add.jsp</result>
                <result name="saveSuccess" type="redirectAction">
                    <param name="namespace">/xxxx</param>
                    <param name="actionName">xxx_xxx</param>
                </result>
                
                <!-- 引入自定义拦截器,拦截此action中所有方法-->
                <interceptor-ref name="privilegeInterceptor"/>
                <interceptor-ref name="defaultStack"/>
            </action>
            
            <action name="user_*" class="com.xxx.web.action.UserAction" method="{1}">
                <result type="redirect">/index.jsp</result>
                <!-- 引入自定义拦截器-->
                <interceptor-ref name="privilegeInterceptor">
                    <!-- 配置excludeMethods节点中的方法不拦截,配置多个方法时以逗号(,)隔开 -->
                    <param name="excludeMethods">login,regist</param>
                </interceptor-ref>
                <interceptor-ref name="defaultStack"/>
            </action>
        </package
  • 相关阅读:
    IBM X System ServerGuide 8.41 服务器 系统安装 引导盘
    oracle查找重复记录
    linux的nohup命令的用法。
    最佳设计工作流
    开发的浏览器颠覆微软,引爆了一场互联网大战
    程序员的成长和代码行数的关系
    Oracle SQL Developer 连接 MySQL
    Linux 如何打开端口
    SQLSERVER中如何快速比较两张表的不一样
    我所理解的MVVM
  • 原文地址:https://www.cnblogs.com/WarBlog/p/14072254.html
Copyright © 2020-2023  润新知