拦截器的 执行过程是一个递归的过程,就相当于过滤器的性质
我的理解是一层层的给action限制,当满足时进入下一层,不满足则退回到上一层
自定义拦截器有两种方法,第一种是实现interceptor接口,第二种方法是继承AbstractInterceptor;AbstractInterceptor抽象类实现了nterceptor接口,并给出了init(),destory()方法的实现,因此一般使用第二种方法来自定义拦截器类
举两个例子来说明拦截器的使用及其作用
第一个例子是计算action执行的时间
定义拦截器类,注意其中的arg0,是管理拦截器的实例,通过调用incoke()执行下一个拦截器
public class TimerIntercepter extends AbstractInterceptor{
@Override
public String intercept(ActionInvocation arg0) throws Exception {
// TODO Auto-generated method stub
long start=System.currentTimeMillis();
String result=arg0.invoke();
long end=System.currentTimeMillis();
System.out.println((end-start)+"ms");
return result;
}
}
在struts.xml中声明拦截器类
<struts>
<package name="default" namespace="/" extends="struts-default">
<!-- 声明 -->
<interceptors>
<interceptor name="myTimer" class="com.imooc.interceptor.TimerIntercepter"></interceptor>
</interceptors>
<!-- 引用 -->
<action name="interceptor" class="com.imooc.action.InterceptorAction">
<interceptor-ref name="myTimer"></interceptor-ref>
<result>/result.jsp</result>
</action>
</package>
</struts>
第二个例子禁止没登录就访问页面
将登录之后显示的页面放在WEB-INF中,客户端只能通过action访问,不能直接访问
action类
//实现获取会话的接口
public class LoginAction extends ActionSupport implements SessionAware{
//由username,password来获取表单中提交的值
private String username;
private String password;
private Map<String, Object> session;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
//在login方法进行判断,当然此处只是简单的判断,按理这里应该是与数据库连接
public String login(){
if("admin".equals(username)&&"123".equals(password)){
session.put("loginInfo", username);
System.out.println(session.get("loginInfo"));
return SUCCESS;
}else{
session.put("loginError", "用户名和密码不正确");
return ERROR;
}
}
//实现SessionAware接口中的方法,获取会话键值对
@Override
public void setSession(Map<String, Object> session) {
// TODO Auto-generated method stub
this.session=session;
}
}
拦截器类
public class AuthInterceptor extends AbstractInterceptor{
@Override
public String intercept(ActionInvocation arg0) throws Exception {
//在拦截器中获取action行为的文本
ActionContext context=ActionContext.getContext();
//通过该文本获取会话的键值对,此值是在action行为中导入的
Map<String, Object> session=context.getSession();
// System.out.println(session.get("loginInfo"));
//返回到<action>中,进行判断
if(session.get("loginInfo")!=null){
String result=arg0.invoke();
return result;
}else{
return "login";
}
}
}
struts.xml
<struts>
<!-- 默认的包名,在没有自定义拦截器时,这种形式会调用defaultStack拦截器 ,但是有自定义拦截器后,就不会调用默认的-->
<package name="default" namespace="/" extends="struts-default">
<!-- 注册拦截器 -->
<interceptors >
<!-- 声明 -->
<interceptor name="auth" class="com.imooc.interceptor.AuthInterceptor"></interceptor>
<!-- 自定义拦截器栈,将多个拦截器放在一起,这里声明了默认的和自定义的 -->
<interceptor-stack name="myStack">
<interceptor-ref name="defaultStack"></interceptor-ref>
<interceptor-ref name="auth"></interceptor-ref>
</interceptor-stack>
</interceptors>
<!-- 通过此Action访问后台管理页面,需要判断用户是否已经登录 -->
<!-- 一个action并不一定需要action的类,默认为SUCCESS;如下所示,(此处返回值由拦截器返回) -->
<action name="auth">
<!-- 当返回为SUCCESS时,执行display.jsp;当返回值为"login"时,执行login.jsp页面 -->
<result>/WEB-INF/back/display.jsp</result>
<result name="login">/login.jsp</result>
<!-- 引用自定义拦截栈 -->
<interceptor-ref name="myStack"></interceptor-ref>
</action>
<!-- 这个是表单提交后执行的行为,从LoginAction的login()方法中返回值,来判断执行的页面 -->
<action name="login" method="login" class="com.imooc.action.LoginAction">
<result>/WEB-INF/back/display.jsp</result>
<result name="error">/login.jsp</result>
</action>
</package>
</struts>