【问题标题】:When should we use and not use forward slash(/) in RequestDispatcher我们什么时候应该在 RequestDispatcher 中使用和不使用正斜杠(/)
【发布时间】:2015-10-28 09:17:11
【问题描述】:

我正在使用 Head First Servlets 和 JSP 中的 RequestDispatcher。我不清楚以下几点

  1. 我们什么时候应该在请求调度器中使用正斜杠(/)?
  2. 我们什么时候不应该在请求调度程序中使用正斜杠(/)?
  3. 相对路径是否应该始终以正斜杠开头?
  4. 以正斜杠 (/) 开头和没有正斜杠 (/) 的相对路径之间的区别。例如 index.html 和 /index.html 之间的区别?

我试过一个例子。下面是我的项目结构和代码

这是我的 Servlet 代码

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        HttpSession session = request.getSession();

        String userId = request.getParameter("userId");
        String password = request.getParameter("password");

        LoginService loginService = new LoginService();
        boolean result = loginService.authenticate(userId, password);
        if(result){
            User userDetails = loginService.getUserDetails(userId);
            request.setAttribute("user", userDetails);
            //response.sendRedirect("success.jsp");
            RequestDispatcher requestDispatcher = request.getRequestDispatcher("success.jsp");
            requestDispatcher.forward(request, response);
            return;
        }else{
            response.sendRedirect("/login.jsp");
            return;
        }
    }

我的登录页面如下

我的成功页面如下

我正在验证登录用户,如果该用户是有效用户,我会将其转发到成功页面。

这里按照我说的代码

 RequestDispatcher requestDispatcher = request.getRequestDispatcher("success.jsp");
            requestDispatcher.forward(request, response);

 RequestDispatcher requestDispatcher = request.getRequestDispatcher("/success.jsp");
            requestDispatcher.forward(request, response);

我的控制权都交给 Success.jsp。在读取请求调度程序时,在 Head First JSP 和 Servlets 中,我无法理解以下行,它是这样的

RequestDispatcher requestDispatcher = request.getRequestDispatcher("result.jsp");

这是一个相对路径,因为没有初始正斜杠(“/”)。所以在这种情况下,容器在请求所在的同一逻辑位置查找“result.jsp”。

如果路径以正斜杠('/") 开头,则容器将其视为“从该 webapp 的根目录开始”。如果路径不以正斜杠开头,则认为它相对于原始请求。

以下内容取自 Head First JSP 和 Servlets。

以上几行是什么意思。我无法清楚地了解“它被认为是相对于原始请求”有人可以举个例子来解释一下吗?

【问题讨论】:

    标签: jsp servlets requestdispatcher


    【解决方案1】:

    UR 开头的正斜杠N 将重定向到应用程序容器/服务器的根目录,并且它在 URN 中的缺失将相对于URL 客户要求

    正斜杠“/”字符用于链接中的 JSP,例如:

    <a href="/foo/stuff.htm">Stuff page</a>
    

    在 servlet 中通过 RequestDispatcher.forward()HTTPResponse.sendRedirect() 方法进行 URL 重定向。

    只有在重定向网址的开头应用时才有效。

    以下是应用程序服务器如何在后台解释它的规则:

    1. 首先:请注意,重定向地址始终区分大小写 - 即使在重定向 URL 的域段中也是如此。请参阅下面的示例代码中的我的 cmets,以通过示例说明什么会起作用,什么会失败。

    2. 如果在重定向中提供了 URL(而不是 URN(要了解区别,请参阅here)) - 例如:如果重定向以“http://”开头,则重定向链接被视为绝对路径。

      否则您的重定向链接将被视为相对链接。

    3. 如果重定向 URI 以正斜杠字符“/”开头,则指示您的应用程序服务器构造一个与 Web 容器相关的 URL!

      例如:相对于localhost:8080

      所以命令...

      response.sendRedirect("/foo/stuff.htm")

      从 servlet 内部,或

      &lt;a href="/foo/stuff.htm"&gt;Stuff page&lt;/a&gt;

      从 JSP 内部,将带您到

      localhost:8080/foo/stuff.htm.

    4. 在您的重定向 URL 开头缺少正斜杠(以及缺少协议签名)将指示应用服务器构造其相对于原始请求 URL 的 URL!即用户在客户端输入浏览器的URL。

      重要的是要知道这个构造的 URL 既不是

      • 相对于领域

        也不

      • 相对于网络容器!

      再次重申:应用服务器构造的 URL 将相对于客户端请求的原始 URL!

      例如:如果客户端提交 URL

      http://www.example.com/level1/level2/stuff.htm

      然后是命令...

      response.sendRedirect("foo/stuff.htm")

      来自 servlet 或,

      &lt;a href="foo/stuff.htm"&gt;Stuff page&lt;/a&gt;

      来自 JSP,会将您重定向到

      http://www.example.com/level1/level2/foo/stuff.htm

      
      
      

      // WILL NOT WORK! Reason: Case sensitivity. response.sendRedirect("/teluskolearnings/login.jsp");

      // WILL WORK! Reason: Case sensitivity. response.sendRedirect("/TeluskoLearnings/login.jsp");

      // Will redirect to localhost:8080/login.jsp as the forward slash tells app // server to build the URL RELATIVE TO THE APP SERVER. // So you will be pointed to '@987654325@'. // This is not what we want. response.sendRedirect("/login.jsp");

      // Will redirect to localhost:8080/TeluskoLearnings/login.jsp // as the ABSENCE of forward slash tells app server to build the URL // RELATIVE TO THE URL! // So you will be pointed to // '@987654326@'. // This IS what we want. response.sendRedirect("login.jsp");

      // Will redirect to localhost:8080/TeluskoLearnings/foo/login.jsp // (you can see the redirection in the address bar, even if you get a // 404 - page not found) as the ABSENCE of forward slash (at the start) tells // app server to build the url RELATIVE TO THE REQUESTED URL! // This also means that if the user entered // '@987654327@"' // he will be pointed to // '@987654328@' // (provided of course, that "/level1/level2/stuff" is captured inside the // urlPatterns parameter of the @WebServlet() annotation). response.sendRedirect("foo/login.jsp");

    查看:https://www.safaribooksonline.com/library/view/head-first-servlets/9780596516680/ch04s27.html

    【讨论】:

      【解决方案2】:

      如果你在这里。

      http://www.example.com/one/two/three/four/five.jsp
      

      然后你通过request.getRequestDispatcher("six.jsp").forward(req, resp);重定向到six.jsp,然后你登陆

      http://www.example.com/one/two/three/four/six.jsp      (relative path)
      

      但是

      如果您通过request.getRequestDispatcher("/six.jsp").forward(req, resp); 重定向到/six.jsp,那么您将登陆

      http://www.example.com/six.jsp      (starting from root)
      

      【讨论】:

      • 请求调度器根本不执行重定向。
      • @BalusC 更新了我的答案。很抱歉声明不完整。感谢您指出:)
      • 问题不在于语句。问题在于术语。转发与重定向不同。
      • 我应该把它改成response.sendRedirect(); 吗?
      • 没有。问题是关于请求调度程序的。您只不断告诉“您重定向到”,但给定的代码根本不执行重定向。它执行前锋。你应该说“你转发到”。请注意,OP 已经使用了正确的术语“转发”。此外,当您执行转发时,浏览器地址栏中的 URL 不会改变。所以“你登陆”的部分也很混乱。阅读食物:stackoverflow.com/a/2048640
      【解决方案3】:

      绝对路径和相对路径各有优劣。

      如果您确定您有一堆 servlet(jsp 是 servlet)都在同一个层次结构级别,并且如果您不想被这个层次结构(前缀)所困扰,那么相对 URL 是合适的。一个真实的示例用例是 javascript 前端服务器后面的 REST 服务器的 servlet - angularjs 开发人员通常使用 REST 服务的相对路径

      相反,如果您希望能够在完整的 Web 应用程序中轻松更改 URL 层次结构,那么绝对 URL 是可行的方法。但在这种情况下,您必须考虑到 servlet 上下文路径,因为您将转发到 本地 路径但重定向到 完整 路径,与:

      full_path = servlet_context_path/local_path
      

      几乎真实的例子:如果 webapp 部署在 http 上,端口 8080 在主机 host.domainwebapp 中,页面 /subdomain1/page1 将有一个完整的 URL http://host.domain:8080/webapp/subdomain/page1,你将使用 /subdomain/page1 转发和/webapp/subdomain/page1 在重定向或链接中。

      【讨论】:

        猜你喜欢
        • 2012-03-25
        • 2021-03-12
        • 2023-02-11
        • 2021-09-07
        • 1970-01-01
        • 2012-11-24
        • 2015-04-23
        相关资源
        最近更新 更多