Strtus2.x 拦截器

本文深入探讨Struts2框架中的拦截器应用,包括自定义拦截器的开发、登录检查和服务器端数据验证。通过实例讲解如何配置拦截器,实现请求前的数据拦截,以及如何利用拦截器进行登录状态检测。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

拦截器是现在开发之中最为重要的特色,是基于AOP的设计思想(AOP是基于代理设计模式思想),面向切面设计思想实现的.

1.清楚拦截器的基本作用;

2.开发自己的拦截器

3.实现登录检查拦截器

4.实现服务器端数据验证拦截器(工具类);

5.拦截器栈的定义及使用

        在Strut2.x里面为了方便用户进行数据的验证,专门提供有validate()方法以及验证框架,但是这两个验证操作都有一个最致命的问题--永远都要在其赋值完成之后才能够验证,赋值之前无法验证,所以后台会一直出现错误,为了解决这样的问题,或者说为了解决所有辅助性的检测的功能.那么可以利用拦截器完成

认识拦截器

        在Struts2.x里面所有的客户端发送过来的请求都交给Filter进行处理,而后由Filter再去决定执行哪个Action.而拦截器是在某一个Action之前做的数据拦截操作

  实际上在之前也有拦截器出现,表单参数类型自动变为vo类型对象,这个就是拦截器的功能,

范例:定义一个Action,手工配置一个拦截器

package cn.jcn.action;
import com.opensymphony.xwork2.ActionSupport;
@SuppressWarnings("serial")
public class MessageAction extends ActionSupport{
    public void insert(){
        System.out.println("插入信息~~~~~~~~");
    }
}

范例:配置一个计算处理事件的拦截器

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN" "http://struts.apache.org/dtds/struts-2.1.dtd">
<struts>
    <package name="root" namespace="/" extends="struts-default">
        <action name="MessageAction" class="cn.jcn.action.MessageAction">
            <interceptor-ref name="timer"></interceptor-ref>
        </action>
    </package>
</struts>    

此时会计算出当前操作的执行时间,而后台的输出效果如下

Executed action [//MessageAction!insert] took 1 ms.

        此时拦截器自动执行了,但是timer这个拦截器默认是在Action之后执行,

开发自定义拦截器

如果要想开发自定义拦截器,那么在Struts2.x里面是由要求的这个拦截器的类必须继承自"com.opensymphony.xwork2.interceptor.AbstractInterceptor"父类,这个类是一个抽象类;

public abstract class AbstractInterceptor
extends Object
implements Interceptor
        在这个类之中存在有三个方法, 但是有一个抽象方法

○拦截:

public abstract class AbstractInterceptor
extends Object
implements Interceptor
        这个方法参数里面接受了一个ActionInvocation的对象,这个类对象可以取得一切的发送及执行信息.

范例:实现一个最基础的拦截器

package cn.jcn.interceptor;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
@SuppressWarnings("serial")
public class MyInterceptor extends AbstractInterceptor{
    @Override
    public void init() {
        System.out.println("-------拦截器初始化------");
    }
    @Override
    public String intercept(ActionInvocation arg0) throws Exception {
        System.out.println("---------拦截器执行----------");
        return arg0.invoke();  //将请求向下传递
    }
    @Override
    public void destroy() {
        System.out.println("----------拦截器销毁---------");
    }
}

 拦截器定义完成固然是一件好事,但是拦截器必须在strtus.xml文件中进行配置.

范例:配置strtus.xml文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN" "http://struts.apache.org/dtds/struts-2.1.dtd">
<struts>
    <package name="root" namespace="/" extends="struts-default">
            <interceptors>
                <interceptor name="jcn" class="cn.jcn.interceptor.MyInterceptor"></interceptor>
            </interceptors>
        <action name="MessageAction" class="cn.jcn.action.MessageAction">
            <interceptor-ref name="timer"></interceptor-ref>
            <interceptor-ref name="jcn"></interceptor-ref>
        </action>
    </package>
</struts>    

此时在MessageAction执行的时候挂了两个拦截器执行结果如下:

---------拦截器执行----------
插入信息~~~~~~~~
六月 05, 2018 10:19:06 下午 com.opensymphony.xwork2.util.logging.commons.CommonsLogger info

信息: Executed action [//MessageAction!insert] took 0 ms.

        此时的拦截器是在Action执行之前进行了处理,等于是说当前已经拦截下来了

范例:现在在Message中定义News类型进行数据接收

package cn.jcn.action;
import com.opensymphony.xwork2.ActionSupport;
 
import cn.jcn.vo.News;
@SuppressWarnings("serial")
public class MessageAction extends ActionSupport{
    private News news = new News();
    public News getNews() {
        return news;
    }
    public void insert(){
        System.out.println(this.news);
        System.out.println("插入信息~~~~~~~~");
    }
}

发现一旦编写了自定义拦截器之后,非常遗憾的问题出现了,自动赋值操作不会出现了,因为在Struts2.x里面你没有使用拦截器,会自动使用赋值的拦截器,而一旦使用了拦截器,那么就需要手工来配置拦截器.

范例:修改配置

<action name="MessageAction" class="cn.jcn.action.MessageAction">
            <interceptor-ref name="timer"/>
            <interceptor-ref name="jcn"/>
            <interceptor-ref name="defaultStack"></interceptor-ref>
        </action>

如果开始编写自定义拦截器,所有的操作必须采用手工的模式进行.

利用拦截器检测登录

            如果要进行登录检测,那么肯定是用过滤器是最合适的,不过遗憾的是Struts2.x为了Struts1.x区别所以使用了过滤器进行整个的分发处理.那么自己写的过滤器自然无法进行session的登录检查.如果要想实现登录检查,那么只能够依靠拦截器完成,也就是说现在必须要对ActionInvocation做进一步研究

这是一个接口com.opensymphony.xwork2.interceptor.AliasInterceptor

请求继续向下传递给Action:

String invoke()
throws Exception
取得上下文对象内容:

ActionContext getInvocationContext()
使用此方法返回的是一个“com.opensymphony.xwork2.ActionContext”类的对象,这个类包含有如下方法:

取得全部的参数:public HttpParameters getParameters()

取得全部Session保存的数据

public Map<String,Object> getSession()
取得全部Application保存的属性数据

public Map<String,Object> getSession()
范例:假设登陆的session属性名称为“mid”,所以本次验证如下

package cn.jcn.interceptor;
import java.util.Map;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
@SuppressWarnings("serial")
public class Logininterceptor extends AbstractInterceptor{
    @Override
    public String intercept(ActionInvocation arg0) throws Exception {
        Map<String, Object> map = arg0.getInvocationContext().getSession();
        if(map.get("mid") != null){
            return arg0.invoke();
        }else{
            ServletActionContext.getRequest().setAttribute("msg", "您还未登录请先登录!");
            ServletActionContext.getRequest().setAttribute("url", "login.jsp");
        }
        return "forward.page";  //全局跳转提示页面
    }
}

但是使用了一个“forward.page”的页面面对于这个页面需要提醒注意,几乎所有的开发之中都需要统一的信息提示页,那么可以定义为全局跳转资源.

范例:修改strtus.xml文件,配置拦截器使用

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN" "http://struts.apache.org/dtds/struts-2.1.dtd">
<struts>
    <package name="root" namespace="/" extends="struts-default">
            <interceptors>
                <interceptor name="jcn" class="cn.jcn.interceptor.MyInterceptor"></interceptor>
                <interceptor name="login" class="cn.jcn.interceptor.Logininterceptor"></interceptor>
            </interceptors>
            <global-results >
                <result name="forward.page">forward.jsp</result>
            </global-results>
        <action name="MessageAction" class="cn.jcn.action.MessageAction">
            <interceptor-ref name="timer"/>
            <interceptor-ref name="jcn"/>
            <interceptor-ref name="login"></interceptor-ref>
            <interceptor-ref name="defaultStack"></interceptor-ref>
        </action>
    </package>
</struts>    

此时已经彻底实现了拦截器的实际使用.

        所有的拦截器都会按照既定的顺序依次向下执行,这一点的控制是非常方便的,因为很多时候是先进行登录验证后再进行其他操作.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值