会话不会失效

时间:2013-07-01 20:29:27

标签: java servlet-filters httpsession

我正在尝试编写一个过滤器,用于检查用户是否已登录,以防万一不将其重定向到登录页面。以前我有过滤器实际上没有做任何事情-_-在这里,并且使用这个过滤器everythig工作正常,会话无效:

public void doFilter(ServletRequest req, ServletResponse res,
        FilterChain chain) throws IOException, ServletException {
    HttpServletRequest request = (HttpServletRequest) req;
    HttpSession session = request.getSession();
    if (session == null || session.getAttribute("UserName") == null) { 
        String command = request.getParameter("command");

        request.setAttribute("command", "login");
        // String page = ConfigurationManager.getInstance().getProperty(
        // ConfigurationManager.LOGIN_PAGE_PATH);

    } else {
        String username = (String) session.getAttribute("UserName");
        UserRole role;
        try {
            role = UserDAOImpl.getUserRole(username);
            session.setAttribute("role", role);
        } catch (DAOTechnicException e) {
            logger.error(e);
        } catch (DAOLogicException e) {
            logger.error(e);
        }
    }
    chain.doFilter(req, res); 
}

当我使会话无效时,它会进入(如果是session == null)块,一切正常。

但现在我有另一个过滤器,这里是:

public class UserCheckFilter implements Filter {

    static class FilteredRequest extends HttpServletRequestWrapper {

        public FilteredRequest(ServletRequest request) {
            super((HttpServletRequest) request);
        }

        public String getParameter(String paramName) {
            String value = super.getParameter(paramName);
            if(value!=null){
                if (value.equals("login")) {
                    return value;
                }

                HttpSession session = super.getSession();
                if (session == null || session.getAttribute("UserName") == null) {
                    value = "login";
                }
            }
            return value;
        }
    }

    /**
     * Checks if user logged in and if not redirects to login page
     */
    @Override
    public void doFilter(ServletRequest req, ServletResponse res,
            FilterChain chain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) req;
        HttpSession session = request.getSession(false);
        if (session == null || session.getAttribute("UserName") == null) {
            if(request.getParameter("command")!=null){
                String command = request.getParameter("command");
                if(!command.equals("login")){
                    FilteredRequest filtrequest = new FilteredRequest(request);
                    String filteredvalue = filtrequest.getParameter("command");
                    chain.doFilter(filtrequest, res);
                }else{
                    chain.doFilter(req, res);
                }
            }else{
                chain.doFilter(req, res);
            }
        } else {
            String username = (String) session.getAttribute("UserName");
            UserRole role;
            chain.doFilter(req, res);
            try {
                role = UserDAOImpl.getUserRole(username);
                session.setAttribute("role", role);

            } catch (DAOTechnicException e) {
                logger.error(e);
            } catch (DAOLogicException e) {
                logger.error(e);
            }
        }

    }

我在其中包装getParameter方法并检查是否未登录用户正在尝试转到用户或管理页面。但是当我使会话无效时,它不会失效,即所有参数保持不变,然后在过滤器中检查是否会话!= null,它不是null,并且在行session.setAttribute(“role”,role) ;我得到例外“会话已经失效”

这是我使会话无效的方法:

    if(request.getSession(false)!=null){
        request.getSession().invalidate();
    }
    String page = ConfigurationManager.getInstance().getProperty(
                ConfigurationManager.LOGIN_PAGE_PATH);
    return page;

并在servlet U中使用

RequestDispatcher dispatcher = getServletContext()
                .getRequestDispatcher(page);
        dispatcher.forward(request, response);

和btw使用无效会话的事情只发生在第二个过滤器

P.S。对不起可能是愚蠢的问题,但我真的不知道出了什么问题, 所以任何建议都会受到赞赏。

1 个答案:

答案 0 :(得分:1)

我认为这是因为你总是在调用chain.doFilter()。

根据Oracle的文档...

  

此方法的典型实现将遵循以下内容   模式: -

     
      
  1. 检查请求
  2.   
  3. 可选择使用自定义实现包装请求对象,以过滤输入过滤的内容或标题
  4.   
  5. 可选择使用自定义实现包装响应对象以过滤内容或标题以进行输出过滤
  6.   
  7. a) 使用FilterChain对象(chain.doFilter())调用链中的下一个实体,
  8.   
  9. b)未将请求/响应对传递给过滤器链中的下一个实体以阻止请求处理
  10.   
  11. 在调用过滤器链中的下一个实体后直接在响应上设置标头。
  12.   

在步骤4中,您可能希望执行(b) - 也就是说,不是将请求传递给链中的下一个过滤器,而是将结果返回给用户。我的意思是,这是一个无效的会话,所以为什么还要尝试进行额外的处理呢?