2010-01-07 97 views
1

我是一个新手servlet程序员。我正在努力做到这一点。设计问题 - 重定向URL

我写了一个过滤器拦截Servlet请求,并检查URL需要先登录用户。如果是这样的用户被定向到登录页面。这是行得通的。但是,我想将用户重定向到他想要去的页面。保持这种状态的正确方法是什么?我只是将URL存储在使用Cookie中的会话ID索引的数据结构中?

回答

1

我写了一个过滤器拦截servlet请求,并检查URL需要在要记录用户

这似乎听起来不错。你还是在Servlet相同url-pattern映射Filter,或更好,但在Servletservlet-name。这样Filter只有调用Servlet时才调用

返回到您的实际问题:在不登录的用户,你有两个选择:

  1. 存储在会话的网址:

    if (session.getAttribute("user") == null) { 
        session.setAttribute("back", httpRequest.getRequestURI()); 
        httpRequest.sendRedirect("login"); 
    } else { 
        chain.doFilter(request, response); 
    } 
    

    您在登录时使用:

    User user = userDAO.find(username, password); 
    if (user != null) { 
        session.setAttribute("user", user); 
        String back = (String) session.getAttribute("back"); 
        if (back != null) { 
         session.removeAttribute("back"); 
         response.sendRedirect(back); 
        } else { 
         response.sendRedirect("home"); // Home page? 
        } 
    } else { 
        // Show error? 
        request.setAttribute("message", "Unknown user, please retry"); 
        request.getRequestDispatcher("login").forward(request, response); 
    } 
    
  2. 传递URL作为请求参数:

    if (session.getAttribute("user") == null) { 
        httpRequest.sendRedirect("login?back=" + httpRequest.getRequestURI()); 
    } else { 
        chain.doFilter(request, response); 
    } 
    
    您通过为隐藏输入字段后续请求

    <input type="hidden" name="back" value="${param.back}"> 
    

    您在登录时使用:

    User user = userDAO.find(username, password); 
    if (user != null) { 
        session.setAttribute("user", user); 
        String back = request.getParameter("back"); 
        if (back != null) { 
         response.sendRedirect(back); 
        } else { 
         response.sendRedirect("home"); // Home page? 
        } 
    } else { 
        // Show error? 
        request.setAttribute("message", "Unknown user, please retry"); 
        request.getRequestDispatcher("login").forward(request, response); 
    } 
    

URL编码的一些建议是没有必要的getRequestURI()将不会被解码。

+0

非常感谢您的详细回复。您的回复为我提供了2分,但我没有解决 - 您说过 - 您应该将过滤器映射到Servlet的相同url模式,或者更好的方式是将Servlet的名称与Servlet名称相关联 这是标准做法吗?我正在为每个功能编写一个过滤器。例如一个用于日志记录,一个用于验证检查。我将这些映射到所有jsps和servlet。 我会在另一条评论中写下第二个问题。 – user220201 2010-01-08 03:13:43

+0

您从字面上说您正在检查过滤器中的URL以查看用户是否需要登录。如果您将过滤器映射到覆盖该URL的'url-pattern',则这是不必要的。或者,如果在同一个'url-pattern'上已经有一些控制器servlet,那么将它映射到该servlet上。无论哪种方式,过滤器都不会被不必要地调用。 – BalusC 2010-01-08 03:20:42

+0

另一个问题是关于使用数据库的认证。到目前为止,我编写了自己的数据库连接类,并自己编写了所有代码或数据库操作。我知道我可以使用Hibernate。但是有没有特定的认证本身?什么是userDAO。另外,Asaph正在讨论tomcat内置的安全支持。大规模应用的首选方式是什么(面向消费者而不是企业)? - 谢谢。 – user220201 2010-01-08 03:44:22

2

您可以将其存储在一个会话也可以将其添加到登录的网址。

http://www.myexample.com/login.jsp?from=mypage.jsp 

确保您url encode它(用适当的转义值替换/,&,=,等等(%XX)),如果它有一个路径和文件名。

http://www.myexample.com/login.jsp?from=mydir%2Fmypage.jsp 
+0

谢谢!我知道这样做会有更好的方式。我是C程序员,所以尝试创建一切的数据结构:) – user220201 2010-01-08 03:08:59

1

不要重新发明轮子。 Servlet API支持基于用户/角色的身份验证和安全性。 Tomcat的(除了别的以外)包括:built in support for authenticating使用各种来源:xml文件,数据库,LDAP等

+0

世界需要多少个验证轮? – Timothy 2010-01-08 14:27:36