通过 Java 过滤器后使用 RequestDispatcher 转发

Posted

技术标签:

【中文标题】通过 Java 过滤器后使用 RequestDispatcher 转发【英文标题】:forwarding with RequestDispatcher after going through Java Filter 【发布时间】:2012-02-15 02:12:13 【问题描述】:

首先让我描述一下我正在尝试做的事情,我猜这很简单。 我有一个包含用户的网站,并且希望仅对已登录的用户访问 view_profile.jsp 页面。我有一个过滤器映射到:

<url-pattern>/auth/*</url-pattern>

看起来像这样

        try 
        HttpSession session = ((HttpServletRequest)request).getSession();
        UserBean user = (UserBean)session.getAttribute("currentUser");
        if (user != null && user.isValid())
            System.out.println("Filter: context -> " + ((HttpServletRequest)request).getContextPath()); //returns ""
            chain.doFilter(request, response);
        
        else
            ((HttpServletResponse)response).sendRedirect("/login.jsp"); //works fine
        

当用户在 index.jsp 页面上点击链接时,此过滤器运行:

<a href="./auth/view_profile?profile=$sessionScope.currentUser.username">
//yeah, he will 'view' himself - it's just an example

假设将用户带到映射到 ViewProfileServlet 的 servlet 映射到:

<url-pattern>/auth/view_profile</url-pattern>

看起来像这样:

    try 
        String username = (String) request.getParameter("profile");

        // here is getting info from database and setting request attributes
        // works fine

                //response.sendRedirect("/view_profile.jsp");
                System.out.println("ViewProfileServlet: In context -> " + getServletContext().getContextPath()); // returns ""
                dis = getServletContext().getRequestDispatcher("/view_profile.jsp");
                // i've tried request.getRequestDispatcher. no difference
                System.out.println("ViewProfileServlet: forward to '/view_profile.jsp'");
                dis.forward(request, response);
            

这又应该将用户带到 /view_profile.jsp(在根上下文中,而不是在 /auth 中)并工作,但事实并非如此。发生的情况是 ViewProfileServlet 运行并且 view_profile.jsp 显示,尽管上下文似乎仍然是 /auth,因为 view_profile.jsp 上的所有链接都指向 localhost:8080/auth/some-page.jsp。此外,没有加载 css 文件,甚至没有请求它们(至少根据 firebug),并且页面源显示 404 Glassfish 错误,其中 css 应该是。

非常感谢任何帮助,这是我第一次在 jsp 中做某事,我完全迷失了。

【问题讨论】:

【参考方案1】:

转发完全发生在服务器端。浏览器对此一无所知。当它向/auth/view_profile 发送请求并从该响应中接收 html 时,他并不关心 HTML 是由 servlet、JSP、两者还是其他任何东西生成的。它读取 HTML 并认为它来自路径 /auth/view_profile。因此,HTML 中的所有相对路径都相对于/auth/view_profile

使用 absolute 路径来引用图像、JS 和 CSS 路径(在大多数情况下甚至是其他操作)要容易得多。只需确保使用 &lt;c:url&gt; 标记生成 URL,以便在 web-app 的上下文路径之前添加:

<script src="<c:url value='/js/myScript.js'/>" type="text/javascript"/>
                           ^-- the slash here makes the path absolute. 

【讨论】:

感谢您的回答。我已将 css 的路径更改为 之一,但会发生一秒钟它请求“localhost:8080/auth/css/styles.css”,它(再次)通过过滤器,然后css请求完全消失。结果是一样的。 路径必须是绝对路径:以/开头。 谢谢 :) Css 工作。但是我应该如何处理页面上的链接?有没有办法让它们不指向 /auth/ 上下文?我试过 但它仍然指向 /auth/logout.jsp

以上是关于通过 Java 过滤器后使用 RequestDispatcher 转发的主要内容,如果未能解决你的问题,请参考以下文章

布隆过滤器

java简单的过滤器实现;

如何通过后端基于过滤器获取计数

markdown 使用ramda通过嵌套值过滤对象数组:有时您无权访问后端,并且您希望过滤来自

Java Web之简单的登录过滤器实现方法

过滤器的使用