拦截器是对调用的Action起作用,它提供了一种机制可以使开发者定义在一个action执行的前后执行的代码,也可以在一个action执行前阻止其执行。同时也是提供了一种可以提取action中可重用的部分的方式,很多业务逻辑都是靠拦截实现的,比如校验,验证登录权限(比如下载时跳转到登陆页面)等等。
下面演示一个简单的struts整合spring拦截器的示例。
导包:
要执行的DemoAction:
package cn.tedu.web;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
//模拟的控制器
@Controller
@Scope("prototype")
public class DemoAction {
public String execute(){
System.out.println("DemoAction");
return "success";
}
}
拦截器DemoInterceptor:
package cn.tedu.web;
import org.springframework.stereotype.Component;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.Interceptor;
//拦截器必须实现接口Interceptor
@Component
public class DemoInterceptor implements Interceptor{
@Override
public void destroy() {}
@Override
public void init() {}
@Override
public String intercept(ActionInvocation invocation) throws Exception {
System.out.println("开始");
String val = "success";
val = invocation.invoke();//调用后续控制器
System.out.println("结束");
return val;
}
}
注意:拦截器必须实现Interceptor接口
struts.xml配置文件:
<package namespace="/" name="test" extends="json-default">
<interceptors>
<interceptor name="wq1" class="demoInterceptor"></interceptor>
</interceptors>
<!-- 此时会先执行name为wq1的拦截器再执行action -->
<action name="demo" class="demoAction">
<interceptor-ref name="wq1"></interceptor-ref>
<result name="success">/WEB-INF/ok.jsp</result>
</action>
</package>
spring的配置文件中需要配置组件扫描即可(配置文件略)
ok.jsp如下:
<%@ page contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>ok</title>
</head>
<body>
<h2>OK!</h2>
</body>
</html>
这时访问地址:http://localhost:8000/struts_day03/demo
执行拦截器,页面输出
开始
DemoAction
结束
另外,如果将拦截器中的这行:val = invocation.invoke();//调用后续控制器,注释掉,则仍然正常工作,跳转到ok.jsp,页面显示正常,输出如下:
开始
结束
但是不会调用action控制器
若在action中需要接收页面参数,则接受不了:在上述基础上如下所示:
package cn.tedu.web;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
//模拟的控制器
@Controller
@Scope("prototype")
public class DemoAction {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String execute(){
System.out.println(name);
System.out.println("DemoAction");
return "success";
}
}
这时候的访问地址:http://localhost:8000/struts_day03/demo?name=Tom
传递参数name=Tom
控制台输出:
开始
null
DemoAction
结束
此时,在action中未接收到传递过来的参数
这是因为我们使用了自定义的拦截器,就会是struts原来的拦截器失去效果,原来的拦截器在struts-default.xml文件中定义了如下:
这时候,在传递参数的时候需要使用该basicStack拦截器栈,在struts.xml配置文件中做出如下修改:
<package namespace="/" name="test" extends="json-default">
<interceptors>
<interceptor name="wq1" class="demoInterceptor"></interceptor>
<!-- 加上如下代码才能传递参数 -->
<interceptor-stack name="mystack">
<interceptor-ref name="basicStack"></interceptor-ref>
<interceptor-ref name="wq1"></interceptor-ref>
</interceptor-stack>
</interceptors>
<!-- 此时会先执行name为wq1的拦截器再执行action -->
<action name="demo" class="demoAction">
<interceptor-ref name="mystack"></interceptor-ref>
<result name="success">/WEB-INF/ok.jsp</result>
</action>
</package>
再次访问地址:http://localhost:8000/struts_day03/demo?name=Tom
控制台输出:
开始
Tom
DemoAction
结束
这是拦截器配置过程中的注意事项
小知识:basicStack和defaultStack在此处都可以使用,里面都有对参数传递的处理,具体代码如下: