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/)

posted @ 2012-08-14 18:32  叶尚海  阅读(1962)  评论(0编辑  收藏  举报