作为Java Web应用程序的开发人员,我何时需要使用URL重写以及URL重写和转发之间的区别?
我在其他网站上搜索过,根据你所说的人,我会得到相互矛盾的信息,比如SEO人会以不同的方式回答这个问题。
AFAIK在这两种情况下,客户端(浏览器)都不会收到有关更改的通知,最终用户会看到客户端在从服务器返回休止符时最初请求的完全相同的URL。
请问这个问题是在Java Servlet API的上下文中,其中定义了forward方法和sendRedirect方法,其中重定向和转发完全是两个不同的东西。这个问题是关于forward(由Servlet API中的forward方法定义)和URL重写之间的区别。问题清楚地表明答案应该在Java servlet的上下文中。最重要的是,我何时需要使用URL重写,再次在开发Java Web应用程序的上下文中。
答案 0 :(得分:8)
在这个问题中,“转发”一词含糊不清。在JSP / Servlet世界中,从MVC概念中可以更加了解“转发”,即请求URL(在浏览器地址栏中可见)有效地调用servlet(与web.xml
或{{3}中的URL模式匹配})充当控制器来准备模型并使用JSP作为视图来呈现模型。反过来,JSP被称为“转发”。这是由@WebServlet
:
request.getRequestDispatcher("/WEB-INF/foo.jsp").forward(request, response);
这确实没有反映浏览器地址栏中的JSP的URL。这完全发生在服务器端。基本上,servlet“加载”JSP并将请求/响应传递给它,以便它可以完成生成HTML内容的工作。请注意,上面示例中的JSP隐藏在/WEB-INF
文件夹中,这使得尝试在浏览器地址栏中输入完整路径的最终用户无法访问它。
在一般的Web开发世界中,术语“转发”也是从“URL转发”中知道的,它与URL重定向基本相同。这反过来确实导致浏览器地址栏的更改。这在JSP / Servlet世界中更正式地称为“重定向”(尽管大多数初学者最初将其与“转发”混淆)。这是由RequestDispatcher#forward()
:
response.sendRedirect("another-servlet-url");
基本上,服务器通过带有Location
标头的HTTP 3nn响应告诉客户端客户端应该在给定的Location
上发出新的GET请求。以上内容实际上与以下内容相同:
response.setStatus(302);
response.setHeader("Location", "another-servlet-url");
由于是指示执行该作业的客户端(webbrowser),您会看到此URL更改反映在浏览器地址栏中。
术语“URL重写”也不明确。在JSP / Servlet世界中,“URL重写”是将会话ID附加到URL的形式,这样无cookie的浏览器仍然可以维护与服务器的会话。您可能曾经在URL中看到;jsessionid=somehexvalue
属性。默认情况下,这不是自动完成的,但大多数基于Servlet的MVC框架都会自动完成。这是由HttpServletResponse#sendRedirect()
或HttpServletResponse#encodeURL()
完成的:
String encodedURL = response.encodeURL(url); // or response.encodeRedirectURL(url)
// Then use this URL in links in JSP or response.sendRedirect().
(反过来是-again-一个含糊不清的术语。使用“URL编码”你通常会想到encodeRedirectURL()
。没有为此提供Servlet API的工具,这通常是由JSTL的percent encoding和URLEncoder#encode()
或者基于servlet的MVC框架提供的任何UI组件(例如JSF的{{<c:url>
或者MVC在技术上更正确地完成{3}})的
在一般的Web开发世界中(特别是使用Apache HTTPD / PHP人员),“URL重写”更为人所知的是Apache HTTPD的mod_rewrite
正在做的事情:将传入的URL映射到具体资源而不反映客户端的URL更改。在JSP / Servlet世界中,这也是可能的,它通常由使用Filter
的{{1}}实现完成。一个众所周知的实现是<c:param>
。
我承认,当我刚刚开始使用JSP / Servlet时,这也让我感到很困惑,当然,我的根源是Apache HTTPD / PHP世界。
答案 1 :(得分:2)
重写是一个层(通常在您的servlet之前),通过在提供请求之前修改URL,使URL像处理不同的URL一样处理。 servlet通过单个请求响应,就像请求重写的URL一样,通常从未知道重写发生过。
当服务器通过Forwarding (or redirection)指示(当客户端允许重定向时),浏览器(通常是自动)执行some 3xx error codes。在这种情况下,将提供两个请求(不一定都来自您的servlet);第一个响应错误代码和重定向到的URL,第二个响应客户端重定向后提供正确的请求。