Struts2知识积累(2)_核心概念:拦截器

本文详细解析了Struts2框架中的拦截器机制,包括其原理、配置方式及实际应用案例,展示了如何通过自定义拦截器实现登录验证等功能。

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

[size=medium]前言[/size]:Struts2的三大组件:动作、拦截器、数据转移。动作组件可能是我们日常中经常接触的。但是在后台默默无闻工作的拦截器,却是真正的核心。在Struts2中没有一个动作被单独调用,总是包含了一系列的拦截器在动作执行之前或之后执行。通过创建一个ActionInvocation的对象,封装了一系列被配置在动作之前或之后触发的拦截器。Struts2提供了一组强大的智能默认值,如defaultStack提供了一个常用的拦截器组合。做web应用时,整个系统的权限设置,日志控制,依靠拦截器可以很方便的的实现。

[size=medium]1.拦截器的原理:[/size]
1.1 总指挥ActionInvocation接口,是理解拦截器的关键。它控制着整个动作的执行,以及与之相关的拦截器栈的执行顺序。当struts2框架接收到一个request-->决定url映射到哪个动作-->这个动作的一个实例会被加入到一二新创建的ActionInvocation实例中-->通过xml配置发现那些触发器按么顺序触发.
public interface ActionInvocation extends Serializable {
Object getAction();
boolean isExecuted();
ActionContext getInvocationContext();
ActionProxy getProxy();
Result getResult() throws Exception;
String getResultCode();
void setResultCode(String resultCode);
ValueStack getStack();
void addPreResultListener(PreResultListener listener);
/**
* Invokes the next step in processing this ActionInvocation.
* <p/>
* If there are more Interceptors, this will call the next one. If Interceptors choose not to short-circuit
* ActionInvocation processing and return their own return code, they will call invoke() to allow the next Interceptor
* to execute. If there are no more Interceptors to be applied, the Action is executed.
* If the {@link ActionProxy#getExecuteResult()} method returns <tt>true</tt>, the Result is also executed.
*
* @throws Exception can be thrown.
* @return the return code.
*/
String invoke() throws Exception;
String invokeActionOnly() throws Exception;
void setActionEventListener(ActionEventListener listener);
void init(ActionProxy proxy) ;
}

框架通过调用ActionInvocation的invoke方法开始动作的执行,但并不总是映射到第一个拦截器,ActinInvocation负责跟踪执行的状态,并且把控制交给合适的拦截器。通过调用拦截器的intercept()方法将控制交给拦截器。.实际应用中编写的拦截器要实现Interceptor接口,通过intercept()方法返回的控制字符串决定页面的跳转,实现登录,权限控制。这就是拦截器的原理。
public interface Interceptor extends Serializable {
void destroy();
void init();
/**
* Allows the Interceptor to do some processing on the request before and/or after the rest of the processing of the
* request by the {@link ActionInvocation} or to short-circuit the processing and just return a String return code.
*
* @param invocation the action invocation
* @return the return code, either returned from {@link ActionInvocation#invoke()}, or from the interceptor itself.
* @throws Exception any system-level error, as defined in {@link com.opensymphony.xwork2.Action#execute()}.
*/
String intercept(ActionInvocation invocation) throws Exception;

}


[size=medium]2.如何应用拦截器:[/size]
Struts2作为一种声明性框架,在建立拦截器也是采用声明的方式构建构建拦截器、构建栈(stack)、向拦截器传递参数。通常大部分的拦截器以已经在struts-default包中提供了,下面贴出部分配置信息。[color=red]记住:xml是声明拦截器的唯一选择。注解机制现在还不能支持声明拦截器[/color].

<?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="struts-default" abstract="true">
<result-types>
<result-type name="chain" class="com.opensymphony.xwork2.ActionChainResult"/>
.........
</result-types>
//interceptorsy元素
<interceptors>
<interceptor name="alias" class="com.opensymphony.xwork2.interceptor.AliasInterceptor"/> .........
//声明拦截器栈
<interceptor-stack name="defaultStack">
<interceptor-ref name="exception"/>
.........
<interceptor-ref name="validation">
<param name="excludeMethods">input,back,cancel,browse</param>
</interceptor-ref>
</interceptor-stack>
</interceptors>
//默认引用
<default-interceptor-ref name="defaultStack"/>
<default-class-ref class="com.opensymphony.xwork2.ActionSupport" />
</package>

</struts>


http://struts.apache.org/dtds/struts-2.3.dtdDTD文件说明:表明Struts.xml的配置文件元素的信息,安装下面条件顺序出现
<!ELEMENT struts (package|include|bean|constant)*>
<!ELEMENT package (result-types?, interceptors?, default-interceptor-ref?, default-action-ref?, default-class-ref?, global-results?, global-exception-mappings?, action*)>

struts.xml配置拦截器说明:interceptors元素包含了这个包(struts-default)内的所有interceptor和interceptor-stack的声明,每一个intercptor元素声明了一个可以在这个包内使用的拦截器,[color=red]只是将一个拦截器的实现类映射到一个逻辑名[/color],class="",就是实现类,这种声明实际上没有创建一个拦截器,或者把这个拦截器与任何动作关联,仅仅是把一个名字映射到一个类。struts-default包内声明了几个拦截器栈,其中最重要的是defaultStack;interceptor-Stack元素的内容是一些列的intercept-ref元素,[color=red]这些引用必须都指向inrerceptor元素创建的某个逻辑名。[/color]如果构建自定义拦截器,创建自己的栈也是这样的简单,栈内的interceptor-ref传入的参数引用自己的拦截器类的逻辑名。[color=red]最后,一个包可以定义一组默认的拦截器,<default-interceptor-ref name=""/>定义的拦截器组会与这个包内没有显式声明自己的拦截器的所有动作关联。[/color],同样默认引用的元素只指向一个逻辑名=defaultStack,当我们继承这个struts-default包时,允许动作继承默认的拦截器栈defaultStack。

[size=medium]3.实际应用拦截器(以用户登录为例)[/size]
先写拦截器的实现类:
public class DemoInterceptor implements Interceptor{
private String msg ;
public void init() {

}
public void destroy() {

}
public String intercept(ActionInvocation actionInvocation ) throws Exception {

/* 获取session对象
* Map session=ActionContext.getContext().getSession();
*/
Map session=actionInvocation.getInvocationContext().getSession();
//判断是否登录
if(session.get("user")==null||"".equals(session.get("user"))){
System.out.println("没有登陆,返回到主页面");
msg="您好,请重新登录...";
actionInvocation.getStack().setValue("msg", msg);
//重新指向登录界面
return "login";
}
else{
//继续动作的调用,将控制权转交给剩余的拦截器及动作
return actionInvocation.invoke();
}
}
}

struts.xml配置文件的书写,定义的是全局拦截器:
<package name="global" extends="struts-default" >
<interceptors>
<interceptor name="demoInterceptor" class="demo.DemoInterceptor"/>
<interceptor-stack name="myStack">
<!--加入默认的defaultStack-->
<interceptor-ref name="defaultStack"/>
<!--加入自己定义的拦截器-->
<interceptor-ref name="demoInterceptor"/>
</interceptor-stack>
</interceptors>
<!--将myStack声明为这个包的默认拦截器栈-->
<default-interceptor-ref name="myStack"/>
<global-results>
<result name="login">/login.jsp</result>
</global-results>
</package>
......

[color=red]如果想在其他包也扩展你写的自定义拦截器,只要在该包的extends="global",就是继承写了自定义拦截器的包[/color]

[size=medium]4.结束:[/size]
上面简单的介绍了我对struts2的拦截器的了解,并且写了个很简单的demo,这个可以有读者扩展。文章肯定是有写错或不完善的的地方,欢迎大家指出,因为我也是个菜鸟...下一篇将是:struts2的数据转移和视图层应用...
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值