Those pages under WEB-INF are accessible using forward method of RequestDispatcher
. Whats wrong with sendRedirect
?
WEB-INF
directory is a private area of the web application, any files under WEB-INF
directory cannot be accessed directly from browser by specifying the URL. Web container will not serve the content of this directory. However the content of the WEB-INF
directory is accessible by the classes/servlets within the application.
sendRedirect()
creates a new browser request
. redirect sends a header back to the browser/client. This header contains the resource url to be redirected by the browser. Then the browser initiates a new request to the given url.
RequestDispatcher
methods like include()/forward()
works internally. It includes/forwards to resources available within the server from where the call is made. This transfer of control is done by the container internally and browser / client is not involved.
Read the Servlet spec 3.0 Directory Structure-10.5
A special directory exists within the application hierarchy named “WEB-INF”. This directory contains all things related to the application that aren’t in the document root of the application. Most of the WEB-INF node is not part of the public document tree of the application. Except for static resources and JSPs packaged in the METAINF/ resources of a JAR file that resides in the WEB-INF/lib directory, no other files contained in the WEB-INF directory may be served directly to a client by the container. However, the contents of the WEB-INF directory are visible to servlet code using the getResource and getResourceAsStream method calls on the ServletContext, and may be exposed using the RequestDispatcher calls.
The pages under WEB-INF
are not accessible from outside the web application.
Now, since using HttpServletResponse#sendRedirect(), a new request is created by client, so the request is actually sent from the browser, and therefore you cannot have WEB-INF
in path to sendRedirect
.
In case of RequestDispatcher, the methods - forward() and include(), doesn't ask the client to create a new request, rather they use the same request to forward to/include a different page from most probably the Servlet Controller. That is why you can give path to a file under WEB-INF
, as you are accessing it from inside the web application only.
RequestDispatcher
forward method pass the control of the request to another servlet or jsp without telling anything about the request dispatch to the client browser. Therefore request dispatch happens completely in the server side, hence you can specify the path
sendRedirect
method stop further processing of the request and send http status code "301" and URL of the location to be redirected to the client browser in the response header. Server does not have control of this request after sending the redirect related HTTP header to the client browser. Client browser sees http status 301 and then it know it should send a new request to the url in "Location" http header which is set by server. and Client browser sends a new request to the new URL and it will be processed by the server as another normal request.Thus sendRedirect is handled through the client browser, so specifying the path does not work.