为什么使用sendRedirect方法无法访问WEB-INF下的JSP页面?

可以使用RequestDispatcher forward方法访问WEB-INF下的那些页面。 sendRedirect什么问题?

WEB-INF下的页面无法从Web应用程序外部访问。

现在,由于使用了HttpServletResponse#sendRedirect() ,客户端会创建一个新请求,因此请求实际上是从浏览器发送的,因此您不能在sendRedirect路径中使用WEB-INF

RequestDispatcher情况下,方法 – forward()include()不要求客户端创建新请求,而是使用相同的请求转发/包含Servlet Controller最不同的页面。 这就是为什么您可以在WEB-INF下提供文件的路径,因为您只能从Web应用程序内部访问它。

RequestDispatcher forward方法将请求的控制权传递给另一个servlet或jsp,而不会将请求调度的任何内容告诉客户端浏览器。 因此,请求调度完全在服务器端发生,因此您可以指定路径

sendRedirect方法停止对请求的进一步处理,并在响应头中发送http状态码“301”和要重定向到客户端浏览器的位置的URL。 将重定向相关的HTTP标头发送到客户端浏览器后,服务器无法控制此请求。 客户端浏览器看到http状态301然后它知道它应该向服务器设置的“位置”http标头中的URL发送新请求。 并且客户端浏览器向新URL发送新请求,并且它将作为另一个正常请求由服务器处理。因此sendRedirect通过客户端浏览器处理,因此指定路径不起作用。

WEB-INF目录是Web应用程序的私有区域, WEB-INF目录下的任何文件都不能通过指定URL直接从浏览器访问。 Web容器不会提供此目录的内容。 但是,应用程序中的类/ servlet可以访问WEB-INF目录的内容。

sendRedirect()创建一个新的浏览器request重定向将标头发送回浏览器/客户端。 此标头包含要由浏览器重定向的资源URL。 然后浏览器向给定的URL发起新请求。

include()/forward()这样的RequestDispatcher方法在内部工作。 它包括/转发服务器内可用的资源。 这种控制转移由容器内部完成,不涉及浏览器/客户端。

阅读Servlet规范3.0目录结构-10.5

名为“WEB-INF”的应用程序层次结构中存在一个特殊目录。 此目录包含与应用程序相关的所有不在应用程序文档根目录中的内容。 大多数WEB-INF节点不是应用程序的公共文档树的一部分。 除了打包在驻留在WEB-INF / lib目录中的JAR文件的METAINF /资源中的静态资源和JSP之外,WEB-INF目录中包含的其他文件不能由容器直接提供给客户端。 但是,使用ServletContext上的getResource和getResourceAsStream方法调用,servlet代码可以看到WEB-INF目录的内容,并且可以使用RequestDispatcher调用公开它们。