【问题标题】:session does not invalidates会话不会失效
【发布时间】:2013-06-29 02:01:39
【问题描述】:

我正在尝试编写一个过滤器,它检查用户是否已登录,以防万一没有将他重定向到登录页面。以前我的过滤器实际上什么也没做 -_- 在这里,使用这个过滤器一切正常,会话无效:

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); 
}

当我使会话无效时,它进入 (if 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);

并且顺便说一句,只有第二个过滤器才会发生这种使会话无效的事情

附言对不起,可能是愚蠢的问题,但我真的不知道出了什么问题, 所以任何建议都将不胜感激。

【问题讨论】:

标签: java servlet-filters httpsession


【解决方案1】:

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

根据 Oracle 的文档...

此方法的典型实现如下 模式:-

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

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

【讨论】:

    猜你喜欢
    • 2021-03-14
    • 1970-01-01
    • 2015-04-26
    • 2017-05-24
    • 2010-10-20
    • 1970-01-01
    • 2012-12-07
    • 2023-03-26
    • 2013-08-29
    相关资源
    最近更新 更多