struts2过滤ajax请求
正如大家知道的那样,interceptor可以过滤action,filter可以过滤任何请求,但无论你是用interceptor还是filter,ajax请求虽然可以被捕获,但仅仅返回一个response,不能完成跳转。对于session超时的处理则显得无能为力。这种情况下我们对interceptor做一个处理,让它针对ajax的请求不做页面跳转,而是通过action将超时结果返回到前端,由前端捕获后再做跳转处理。过滤器主要代码如下:
public String intercept(ActionInvocation invocation) throws Exception { Map<String, Object> session = invocation.getInvocationContext().getSession(); HttpServletRequest request = ServletActionContext.getRequest(); User user = (User) session.get(SID); if (user == null && isAjaxRequest(request)) { BaseAction action = (BaseAction)invocation.getAction(); action.setTimeout(true); }else if(user == null){ return TIMEOUT; } return invocation.invoke(); } private boolean isAjaxRequest(HttpServletRequest request) { String header = request.getHeader("X-Requested-With"); if (header != null && "XMLHttpRequest".equals(header)) return true; else return false; }
BaseAction是一个抽象类,我所有的actioin都继承于此aciton,此action中包含timeout变量,我并没有直接将它返回到客户端,而是封装到result中,因为result还可能包含其它的信息,主要代码如下:
public static final String RESULT = "result"; protected boolean timeout = false; protected Map<String, Object> result = new HashMap<String, Object>(); public void setTimeout(boolean timeout) { this.timeout = timeout; } public Map<String, Object> getResult() { return result; }
因为BaseAction是一个抽象类(当然你的不一定非得是抽象类,因为我有抽象方法要在子类中实现),它必须由具体的子类产生实例,比如我这里有一个MenuAction的子类,它有一个方法叫addMenu:
public String addMenu(){ if(timeout){ result.put("timeout", true); }else{ menuService = (IMenuService) ctx.getBean(MENUSERVICE); menuService.saveMenu(name, description, parent_id, sequence); result.put("success", true); } return RESULT; }
这里的RESULT是从父类中继承而来,我们看到根据timeout的值去返回不同的result,struts2的主要配置:
<interceptors> <interceptor name="loginInterceptor" class="com.guohe.common.LoginInterceptor"></interceptor> </interceptors> <global-results> <result name="timeout">/view/Timeout.jsp</result> </global-results> <action name="*_Menu" class="com.guohe.action.MenuAction" method="{1}"> <result name="success">/view/menu.jsp</result> <result name="result" type="json"> <param name="root">result</param> </result> <interceptor-ref name="defaultStack" /> <interceptor-ref name="loginInterceptor"></interceptor-ref> </action>
前端主要代码:
function submit(){ var url = "${ctx}/view/addMenu_Menu.action"; var params = {}; jQuery.post(url, params, callbackFun, 'json'); } function callbackFun(res){ if(res.timeout == true){ location.href = "login.jsp"; return; } ... }
我们看到在回调函数里面是可以获取是否超时的,如果超时了就跳转到登录页面,没有超时再做其它逻辑处理。(在不断的尝试中总结经验,以帮助后面的人更快的上路,http://zhs.guohe.in/)