意义
拦截器实际上是AOP的一种实现策略(面向切面编程),动态拦截Action调用的对象,定义在Action执行前后执行代码或在Action执行前阻止其执行代码,同时提供了一种提取Action中可重用部分的方式,实现一些横切关注点的切入。
原理
拦截器方法通过代理的方法来调用;系统需要一个代理工厂,作用是根据目标对象生成一个代理对象;实现原理涉及到Java的反射和动态代理。
作用
完成一些通用控制逻辑:解析请求参数,类型转换,输入校验封装请求参数,防止表单重复提交等。每个拦截器功能内聚,只完成一项拦截增强功能,根据需要搭配组合成拦截器栈,完成更大力度的拦截。
内建拦截器
Struts2内建了大量拦截器,以name-class对形式配置在struts-default.xml文件中,通过继承默认的struts-default包即可使用它们。
主要的内建拦截器简介:
autowiring :自动装配,主要用于Struts2与Spring整合时
chain:构建Action链,使当前Action可访问前一个Action的属性
conversionError:处理类型转换错误;
exception:处理异常,将异常映射为结果;
fileUpload:文件长传时解析表单文件中文件域的内容;
i18n:支持国际化;
modelDriven:用于模型驱动;
servletConfig:支持Action直接访问Servelt API;
token:阻止表单重复提交;
validation :执行在XXXAction-validation.xml中定义的校验器完成数据校验;
workflow:负责调用Action类中的validate方法,如校验失败则返回input逻辑视图;
配置拦截器
要点:拦截器栈中可以嵌套拦截器栈,为拦截器指定参数的有两个时机,一个是定义拦截器时(通过元素)指定参数值作为默认值,一个是在使用拦截器时(通过元素)指定参数值。系统配置默认的拦截器,但是只用当Action中没有显式配置拦截器时,其所在包的拦截器才有效,否则需要手动配置默认拦截器(
代码示例:
<action name="up_*" class="com.iotek.action.UploadAction" method="{1}">
<param name="savepath">upload</param>
<interceptor-ref name="defaultStack"/>
<interceptor-ref name="fileUpload">
<param name="allowedTypes">image/bmp,image/gif</param>
</interceptor-ref>
<result name="input">index.jsp</result>
<result name="success">/WEB-INF/content/success.jsp</result>
<result name="error">/WEB-INF/content/fail.jsp</result>
</action>
完整代码演示拦截器
login.jsp
<body>
<s:actionerror/>
<form action="intercepterAction_execute" method="post">
姓名:<input type="text" name="name"><br>
密码:<input type="password" name="password"><br>
<input type="submit" value="登录">
</form>
</body>
TestIntercepter.java(拦截器)
public class TestIntercepter extends AbstractInterceptor{
private String name;
private String password;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public void init() {
// TODO Auto-generated method stub
System.out.println("这是初始化方法!!");
}
@Override
public String intercept(ActionInvocation invocation) throws Exception {
HttpServletRequest req = (HttpServletRequest)invocation.getInvocationContext().get(ServletActionContext.HTTP_REQUEST);
HttpServletResponse resp=(HttpServletResponse)invocation.getInvocationContext().get(ServletActionContext.HTTP_RESPONSE);
String name=req.getParameter("name");
String password=req.getParameter("password");
System.out.println("名字是:"+name+"密码是:"+password);
if(name!=null){
return invocation.invoke();
}else{
((ActionSupport)invocation.getAction()).addActionError("请登录");
return Action.LOGIN;
}
}
}
IntercepterAction.java
public class IntercepterAction extends ActionSupport {
public String execute(){
return this.SUCCESS;
}
}
struts.xml文件
<struts>
<constant name="struts.enable.DynamicMethodInvocation" value="true" />
<package name="default" namespace="/" extends="struts-default">
<interceptors>
<interceptor name="testIntercepter" class="com.iotek.intercepter.TestIntercepter">
</interceptor>
</interceptors>
<global-results>
<result name="login">index.jsp</result>
</global-results>
<action name="intercepterAction_*" class="com.iotek.action.IntercepterAction" method="{1}">
<interceptor-ref name="testIntercepter">
</interceptor-ref>
<interceptor-ref name="defaultStack"/>
<result name="input">index.jsp</result>
<result name="success">/WEB-INF/content/success.jsp</result>
<result name="fail">/WEB-INF/content/fail.jsp</result>
</action>
</package>
</struts>