想拦截某个action中的方法,判断有没有登陆,没有登陆就拦截。以前不太会用,用的是过滤器。
现在总结一下拦截器:
1:写拦截器类
public class AuthorizationInterceptor extends MethodFilterInterceptor{
private static final long serialVersionUID = 1L;
protected String doIntercept(ActionInvocation invocation) throws Exception {
ActionContext ctx = invocation.getInvocationContext();
Map<String,Object> session = ctx.getSession();
Object object = session.get("sessionUser");
if(object != null){
System.out.println("拦截器:登陆了,走吧走吧~");
return invocation.invoke();
}else{
System.out.println("拦截器:小子,你还没登陆呢");
return Action.LOGIN;
}
}
}
2:配置xml
<package name="manage" namespace="/manage" extends="json-default">
<interceptors>
<interceptor name="authority" class="com.xuedou.skypas.aop.AuthorizationInterceptor"/><!-- 定义一个拦截器 -->
<interceptor-stack name="myStack"> <!-- 定义一个拦截器栈 -->
<interceptor-ref name="authority"><param name="excludeMethods">login</param></interceptor-ref><!-- 引用拦截器 -->
<interceptor-ref name="defaultStack"></interceptor-ref>
</interceptor-stack>
</interceptors>
<default-interceptor-ref name="myStack"></default-interceptor-ref> <!-- 设置全局,默认的拦截器栈 -->
<global-results> <!-- 全局视图。注意顺序,先找action中的视图,如果没有,在进入全局视图 -->
<result name="login">/login.jsp</result> <!-- 跳转的页面 -->
</global-results>
<action name="sys_*" class="userManageAction" method="{1}">
<!-- 方法 -->
</action>
</package>
其中<param name="excludeMethods">login</param>是过滤掉action中login这个方法,不被拦截。需要设置多个,以逗号隔开。
注:每一个拦截器都有两个默认的参数:
excludeMethods - 过滤掉不使用拦截器的方法
includeMethods – 使用拦截器的方法
----------------------------------------------------------------------------
注意:如果想用excludeMethods过滤掉方法的话,需要使拦截器类继承MethodFilterInterceptor才可以,否则无效。
自定义interceptor:
1. implements Interceptor的自定义interceptor
2.extends AbstractInterceptor(AbstractInterceptor 继承了Interceptor接口)
3.extends MethodFilterInterceptor(MethodFilterInterceptor继承了AbstractInterceptor类)
相关资料:http://blog.csdn.net/forwayfarer/article/details/2955467
关于拦截器要注意的地方:
1.自定义拦截器一定要配置,<interceptor-ref name="defaultStack"></interceptor-ref>,因为struts2的默认配置就是默认拦截器。自定义拦截器会把它覆盖,所以要加上来。
interceptor-stack是一堆拦截器组成的一个拦截器栈。也可以当拦截器使用。
interceptor-ref (1)可以在<action...></action>内指定 用哪个拦截器,如:<interceptor-ref name="loginStack" />(同拦截器和action在同一个package中无需继承,如上代码,不同包中action所在的package需要继承自定义拦截器的那个包)(2)可以是一个interceptor (3)也可以是一个interceptor-stack
2013年2月23日16:11:09 更新 解决问题:拦截json请求,让其页面跳转
在使用拦截器的过程中,又遇到了一个问题:
问题:上面的拦截器可以拦截不是json的请求,若遇到json请求,则不跳转页面
解决办法:拦截器中判断是否为ajax异步请求,如果是,则封装一个json返回值,然后在页面用ajaxComplete(function(event,xhr,settings)函数进行判断
(1)AuthorizationInterceptor类, 增加如下isAjaxRequest方法,判断是否为ajax的方法
private boolean isAjaxRequest(HttpServletRequest request) {
String header = request.getHeader("X-Requested-With");
if (header != null && "XMLHttpRequest".equals(header))
return true;
else
return false;
}
(2)doIntercept方法改为
HttpServletRequest request = ServletActionContext.getRequest();
Object object = ActionContext.getContext().getSession().get("sessionUser");
if(object != null){
return invocation.invoke();
}else{
if(isAjaxRequest(request)){ //判断是否为json请求
ValueStack stack = invocation.getStack();
Map<String, Object> returnResult = new HashMap<String, Object>();
stack.set("returnResult", returnResult);
returnResult.put("PERMISSION", "NO"); //存入json值
return "input";
}else{
return "loginPage";
}
}
(3)struts.xml更改,在global-results里加上
<result name="input" type="json"><param name="root">returnResult</param></result>
(4)页面接收到json值 跳转
//异步请求,拦截的返回值(所有的json请求返回后执行的方法)
$(document).ajaxComplete(function(event,xhr,settings){
if(xhr.responseText=='{"PERMISSION":"NO"}'){ //验证是否为登陆状态
window.location.href = PATH + "/#manage"; //跳转页面
}
});