将会话变量从jsp传递到servlet过滤器

时间:2011-09-08 14:00:56

标签: jsp session variables servlets servlet-filters

我刚刚编写了我的第一个servlet过滤器,并且已经出现了问题。我想要做的是进行过滤器句柄身份验证,以便在请求受保护的页面时,过滤器将切入并重定向到登录页面。如果登录成功,则过滤器会将用户重定向到请求的原始页面。

举一个例子,其中一个页面是博客页面。当用户点击“发表评论”时,如果他尚未登录,则过滤器会将其重定向到登录页面。直到这里,过滤器才能完成它的工作。然后用户登录并检查用户名/密码。如果它们没问题,则在jsp中设置会话变量,并再次将页面重定向到评论页面。该请求通过过滤器检查会话变量。但无论如何,我从请求中获得的会话似乎是一个没有设置属性的新会话。我试过调用request.getSession(false),似乎总是返回null。所以不要给我回到我的jsp页面共享的相同会话。

我正在使用tomcat 7.0.2。我不知道这是否是特定于tomcat的,或者只有一些非常明显的东西我不知道。

希望你能帮帮我。

吉斯利

- 更新 -

这是我的代码。猜猜这会很有帮助:)。

基本上,我有一个登录页面,一个博客页面和一个评论页面。在博客页面上,我有这个链接:

<a href="?page=blogg/komment.jsp?id=<%=blog.getID()%>"> Leave comment </a>

在我的过滤器中,我有这个:

public void doFilter(ServletRequest req, ServletResponse res,
        FilterChain chain) throws IOException, ServletException {
    // TODO Auto-generated method stub
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse)res;
HttpSession session = request.getSession(false);

Object userObj = null;
if( session != null ) {
    userObj = session.getAttribute( "username" );
}
String contextPath = request.getContextPath();
String queryString = request.getQueryString();
String url = request.getRequestURI();

String page = request.getParameter("page");

String user = "<user>";
if( userObj != null )
    user = userObj.toString();

if( page == null )
    page = "<page>";

if( userObj == null && page.indexOf( "blogg/komment.jsp" ) != -1 ) {
    session.setAttribute( "destPage", page );
    response.sendRedirect( "index.jsp?page=blogg/login.jsp" );
}

System.out.println( ", Time "
                    + new Date().toString() + " " + page + " " + user);

chain.doFilter(req, res);
}

到目前为止,这么好。这会将我重定向到登录页面。在那里,我这样做:

    String user = request.getParameter( "username" );
    String pass = request.getParameter( "password" );

    if( blog.confirmUser( user, pass ) ) {
      session.setAttribute( "username", user );
      Object destPageObj = session.getAttribute( "destPage" );
      String destPage = "xxx";
      if( destPageObj != null )
          destPage = destPageObj.toString();
      response.sendRedirect( "index.jsp?page=" + destPage );

      %>
      User exists
<%
    }
    else {
%>
    User does not exist
<%
    }

字符串“User exists”永远不会被打印出来,但它总是出现,我得到了登录页面。

这是我不明白的。我设置会话变量“username”,以便当下一个请求到达过滤器时,该变量应包含一个值。但它似乎总是空洞的。实际上,当我在过滤器中调用getSession(false)时,我总是返回null。即使会话变量应该始终存在于JSP中,如果它没有表达。

我已尝试在页面之间传递会话变量,并且完美无缺。但是要在页面中设置会话变量并在下一次重定向中将其读回,总是会失败。

我觉得有一种非常明显的东西让我盯着我,我只是花了很长时间才看到它!

希望你们能帮忙!

- 进一步更新 -

写作评论的空间太小:)。我想做的就是这个。我想让我的jsp页面独立于登录页面。即我希望过滤器充当中介。因此,当我将用户发送到我的评论页面时,我不需要担心他是否登录。如果他没有登录,过滤器应该将他重定向到登录页面,然后将他发送到原始目的地。我的博客不是唯一需要身份验证的东西,我希望将这些逻辑放在同一个地方。

出于安全原因,我不想传递用户名/密码作为请求参数。我希望两者都保留为会话属性。

当你说我在登录页面做的事情应该在过滤器中完成时,我不明白你的意思。我需要一个页面来询问用户他的用户名和密码,我不想发送这些请求。我在这里看到了一个例子,link这正是我想要做的。除非由于某种原因这不起作用,因为我似乎无法访问存储用户名的同一会话。

如果我完全弄错了,你能指点我这样做的网页吗?我花了几个小时谷歌搜索,我发现的所有例子似乎都适合每个人,除了我:)。

1 个答案:

答案 0 :(得分:1)

经过大量的谷歌搜索和挖掘后,我解决了这个问题。

我没有提到的一件事是,我让Tomcat在代理后面运行。并且代理没有提供会话cookie。在我的虚拟主机定义中,我有这个:

    <IfModule proxy_module>
        ProxyRequests Off 
        ProxyPass / http://b6.is:8080/B6/
        ProxyPassReverse / http://b6.is:8080/B6/
    </IfModule>

因此,所有内容都从根目录传递给B6 webapp。

我只需要翻译cookie路径就是添加这一行:

        ProxyPassReverseCookiePath  /B6 /

现在它完美无缺。