0

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

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

顺便说一句,使会话无效的事情仅在第二个过滤器中发生

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

4

1 回答 1

1

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

根据 Oracle 的文档...

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

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

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

于 2013-07-01T20:47:13.353 回答