在Java Servlet上下文中,URL重写和转发之间有什么区别?

问题描述

“转发”一词在这个问题上是模棱两可的。在JSP / Servlet世界中,从MVC概念中可以更进一步地了解到“转发”,即请求URL(在浏览器地址栏中可见)有效地调用了servlet(与web.xml或中的URL模式匹配),该servlet@WebServlet充当了控制器的准备工作。模型,并使用JSP作为视图来展示模型。反过来,该JSP被称为“转发”。这是通过RequestDispatcher#forward()

request.getRequestdispatcher("/WEB-INF/foo.jsp").forward(request, response);

实际上,这并没有在浏览器地址栏中反映JSP的URL。这完全发生在服务器端。基本上,servlet“加载” JSP并将请求/响应传递给它,以便它可以完成生成HTML内容的工作。请注意,以上示例中的JSP隐藏在/WEB- INF文件夹中,这使得最终用户无法在浏览器地址栏中输入其完整路径。

在一般的Web开发世界中,术语“转发” 从“ URL转发”中得知,它与URL重定向基本相同。这确实会导致浏览器地址栏中的更改。这在JSP / Servlet世界中更正式地称为“重定向”(尽管大多数入门者最初将其与“转发”混淆了)。这是通过HttpServletResponse#sendRedirect()

response.sendRedirect("another-servlet-url");

基本上,服务器通过带有Location标头的HTTP 3nn响应来告知客户端,客户端应在给定上发出新的GET请求Location。上面的内容实际上与以下内容相同:

response.setStatus(302);
response.setHeader("Location", "another-servlet-url");

由于指示客户(网络浏览器)执行此工作,因此您会看到此URL更改反映在浏览器地址栏中。

术语“ URL重写” 也是 模棱两可的。在JSP / Servlet世界中,“ URL重写”是将会话ID附加到URL的形式,以便无cookie的浏览器仍可以维护与服务器的会话。您可能会;jsessionid=somehexvalue在URL中看到一个属性认情况下,这不是自动完成的,但是大多数基于Servlet的MVC框架都会自动完成。这是通过HttpServletResponse#encodeURL()或完成的encodeRedirectURL()

String encodedURL = response.encodeURL(url); // or response.encodeRedirectURL(url)
// Then use this URL in links in JSP or response.sendRedirect().

(这反过来又是一个不明确的术语。使用“ URL编码”,您通常会想到 百分比编码。为此没有提供Servlet API的功能,通常这可以通过URLEncoder#encode()MVC或技术上更正确的方法来完成,由JSTL<c:url>和/<c:param>或基于Servlet的MVC框架提供的任何UI组件(例如JSF<h:outputLink>)在JSP中

在一般的Web开发世界中(尤其是使用Apache HTTPD / PHP的人们),“ URL重写”被称为Apache HTTPDmod_rewrite所做的任何事情:将传入的URL映射到 具体的 资源而不反映客户端的URL更改。在JSP / Servlet世界中,这也是可行的,通常是通过使用Filter实现的Requestdispatcher#forward()一个著名的实现是Tuckey的URLRewriteFilter

我承认,当我刚开始使用JSP / Servlet时,这也使我很困惑,这肯定是因为我扎根于Apache HTTPD / PHP世界。

解决方法

作为Java Web应用程序的开发人员,我什么时候需要使用URL重写,URL重写和转发之间有什么区别?

我在其他网站上搜索时,会得到相互矛盾的信息,具体取决于您与之交谈的对象,例如SEO,人们对这个问题的回答会有所不同。

在这两种情况下,AFAIK都不会向客户端(浏览器)通知更改,并且最终用户会在从服务器返回休假时看到与客户端最初请求的URL完全相同的URL。

请注意,这个问题是在Java Servlet
API的上下文中定义的,其中forward方法和sendRedirect方法在其中重定向和转发是完全不同的两件事。这个问题是关于正向(由Servlet
API中的正向方法定义的)和URL重写之间的区别。该问题明确指出答案应在Java servlet的上下文中。最重要的是,在开发Java
Web应用程序的背景下,何时需要使用URL重写。