您的位置:首页 > 编程语言 > Java开发

轻量级JavaEE企业应用实战(十八)

2015-12-28 14:08 489 查看

详解Struts2的拦截器机制

Struts2拦截器是可插拔式的设计:如果需要使用某个拦截器,只需要在配置文件中应用该拦截器即可;如果不需要,则不需要在配置文件中配置;

拦截器在Struts2中的作用

对于任何MVC框架,他们都会完成一些通用的逻辑控制、例如:解析请求参数、类型转换,将请求参数封装成DTO,执行输入校验,解析文件上传表单中的文件域等;

早期的Struts1把这些动作写在核心控制器里,缺点:

灵活性非常差:强制所有项目都必须使用该框架提供的全部功能,无论是否需要,核心控制器总会完成这些操作

可扩展性很差:如果需要让核心控制器完成更多自定义的处理,需要扩展可信控制器;

Struts2:把大部分核心控制器需要完成的工作按功能分开定义,每个拦截器完成一个功能,这些拦截器自由选择,灵活组合;绝大多数功能是通过这些拦截器来完成的,当StrutsPrepareAndExecuteFilter拦截到用户请求之后,大量拦截器会对请求进行处理,然后才会调用用户开发的Action实例进行处理

Struts2内建的拦截器

这些拦截器配置在struts-default.xml中,如果我们定义的package继承了struts-default包,就可以自由使用这些拦截器,否则需要自行定义;

配置拦截器
<interceptor name="拦截器名" class="拦截器实现类" />

<interceptor name="拦截器名" class="实现类">
<param name="参数名">参数值</param>
</interceptor>

配置拦截器栈:可配置多个
<interceptor-stack>
<interceptor-ref name="拦截器名" />
</interceptor-stack>


配置默认拦截器

当配置一个包时,可以配置其指定默认拦截器。一旦某个包指定了默认拦截器,Action中没有显式指定拦截器,则默认拦截器会起作用;如果一旦为包中的Action显式应用了某个拦截器,则默认拦截器失效;如果该Action需要默认拦截器,必须手动添加该拦截器的引用

<package name="包名">
<interceptors>
<interceptor .../>
<interceptor-stack .../>
</interceptors>
<default-interceptor-ref name="拦截器名或拦截器栈名" />
<action .../>
</package>
注:每个包只能定义一个默认拦截器;如果需要多个拦截器共同作为默认拦截器,可以将这些拦截器配置成拦截器栈,然后把该拦截器栈配置成默认拦截器


实现拦截器类

开发自己的拦截器,需要实现com.opensymphony.xwork2.interceptor.Interceptor类

public interceptor Interceptor extends Serializable {
void destory();
void init();
String intercept(ActionInvocation invocation) throws exception;
}

此外,还实现了一个AbstractInterceptor类,已经实现了destory和init方法,所以只需要继承AbstractInterceptor,实现更加简单

public class SimpleInterceptor extends AbstractInterceptor {
private String name;
...
public String intercept(ActionInvocation invocation)
throws Exception {
LoginAction action = (LoginAction)invocation.getAction();
long start = System.currentTimeMillis();
//执行该拦截器的后一个拦截器,如果没有,则执行execute方法
String result = invocation.invoke();
long end = System.currentTimeMillis();
}
}


拦截方法的拦截器

public class MyFilterInterceptor extends MethodFilterInterceptor {
private String name;
...
public String doInterceptor(ActionInvocation invocation)
throws Exception {
LoginAction action = (LoginAction)invocation.getAction();
long start = System.currentTimeMillis();
//执行该拦截器的后一个拦截器,如果没有,则执行execute方法
String result = invocation.invoke();
long end = System.currentTimeMillis();
}
}

重写的是:doInterceptor方法,继承的是MethodFilterInterceptor
原因:MethodFilterInterceptor是AbstractInterceptor的子类,实现了intercept方法,提供了一个doInterceptor抽象方法;可以说已经实现了对Action的拦截行为,但真正的逻辑需要重写doInterceptor来实现;

<interceptors>
<interceptor name="mysimple" class="com.interceptor.
MyFilterInterceptor">
<param name="name">..</param>
</interceptor>
</interceptors>

<action name="login" class="com.action.LoginAction">
<result name="error">error.jsp</result>
..
<interceptor-ref name="defaultStack" />
<interceptor-ref name="mysimple">
<param name="excludeMethods">execute,test</param>
<param name="includeMethods">execute</param>
</interceptor-ref>
</action>

excludeMethods参数指定:execute和test方法不需要被拦截,又通过includeMethods参数指定execute方法需要拦截;
两者冲突,以includeMethods参数指定的为准,即execute被拦截


Struts2中提供了这种过滤的拦截器有几个:

TokenInterceptor

TokenSessionStoreInterceptor

DefaultWorkflowInterceptor

ValidationInterceptor

拦截器执行顺序

在Action的控制方法执行之前,位于拦截器链前边的拦截器将先发生作用,在Action的控制方法执行后,位于拦截器链前边的拦截器后发生作用
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: