Issue
I am writing a Servlet Controller.If I dont pass any parameter, it will catch Exception and response will sendRedirect to index.jsp
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException, Exception {
response.setContentType("text/html;charset=UTF-8");
RequestDAO requestDAO = new RequestDAOImpl();
try (PrintWriter out = response.getWriter();) {
// get request
int rId = Integer.parseInt(request.getParameter("rId"));
Request req = requestDAO.getRequestById(rId);
sendDispatcher(request, response, "viewRequestMentor.jsp");
} catch (Exception e) {
Logger.getLogger(ViewMentorRequestDetailController.class.getName()).log(Level.SEVERE, null, e);
session.setAttribute("error", "Cant view request detail");
response.sendRedirect("index.jsp");
}
}
But the redirect does not work and the logger display an Exception
Severe: java.lang.IllegalStateException
at org.apache.catalina.connector.ResponseFacade.sendRedirect(ResponseFacade.java:518)
at controller.ViewMentorRequestDetailController.processRequest(ViewMentorRequestDetailController.java:76)
at controller.ViewMentorRequestDetailController.doGet(ViewMentorRequestDetailController.java:103)
Solution
The problem you are having is that you are using try with resources here:
try (PrintWriter out = response.getWriter();) {
And that means that when the try
/catch
block is finished the PrintWriter
is closed. The PrintWriter
is what is used to print the response (the body, the headers and everything that conforms an HTTP Response), and if it is closed, no one can print anything to it.
sendRedirect
is just a normal HTTP response with code 302 that should be written to the response object (HttpServletResponse
), and has a header Location
informing where it should be redirected to. If you open the "Network" tab in you browser's debug you will see that two requests are being made, one for your original Servlet
, and another one for the redirect.
You actually don't have to close the PrintWriter
, as it is the Servlet container (or Application Server, or whatever you are using) the responsible to do that, after everything is properly set. The HttpServletResponse
implies much more that the things we do in the doGet
/doPost
methods, it has a full lifecycle in which we intervene in the middle, we receive it in the doGet
/doPost
/do...
and hand it back to the next Servlet Container bean responsible to do stuff in there.
So, just remove the try
with resources and obtain the PrintWriter
without closing it. The redirect should then work fine.
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException, Exception {
response.setContentType("text/html;charset=UTF-8");
RequestDAO requestDAO = new RequestDAOImpl();
try {
PrintWriter out = response.getWriter();
// get request
int rId = Integer.parseInt(request.getParameter("rId"));
Request req = requestDAO.getRequestById(rId);
sendDispatcher(request, response, "viewRequestMentor.jsp");
} catch (Exception e) {
Logger.getLogger(ViewMentorRequestDetailController.class.getName()).log(Level.SEVERE, null, e);
session.setAttribute("error", "Cant view request detail");
response.sendRedirect("index.jsp");
}
}
Answered By - gmanjon
Answer Checked By - Willingham (JavaFixing Volunteer)