8

I've got a jsp file, which includes another jsp file to check some values and such:

<jsp:include page="setup.jsp" />

Inside the setup.jsp I've got some conditional code which determines if some needed values are set in the session and if not redirects them to a different page. Or at least it is supposed to, but the redirect seems to be getting ignored.

System.err.println("Redirecting!");
response.sendRedirect("http://www.google.com");
return;

I see "Redirecting!" get logged to the console, but the page continues on and renders normally. I had curl dump the headers for me and saw that the response is HTTP/1.1 200 OK so it definitely isn't sending a 302 redirect.

Any idea what the problem is and how I can fix this?

EDIT: I have verified that my response is not yet committed. response.isCommitted() returns false meaning the status code and headers have not been sent yet.

EDIT 2: I've tried calling response.sendRedirect() in many other places and find that I can successfully redirect before the . The redirect inside the JSP seems to be ignored and if I try to redirect right AFTER the jsp then I get an illegal state exception because the response has already been committed.

Kenny Wyland
  • 20,844
  • 26
  • 117
  • 229
  • 1
    There's a chance that part of the response is alredy sent to the client and the redirect is ignored. The redirect should be (almost) the first thing to be parsed. – Augusto Jul 09 '11 at 22:55
  • I have to fit this within a much larger web app structure, so my hands are tied when it comes to when and where I can place the code to do the redirect. Is there a way I can test to see if the response is already delivered content back to the browser when I'm trying to do my redirect? Do you have any suggestions for how I can initiate some kind of redirect when I'm buried in jsp:includes? – Kenny Wyland Jul 09 '11 at 23:03
  • I added a simple out.println() message to the location where I am calling redirect and that output appears before any other output from the response. So shouldn't I be allowed to redirect at that point? – Kenny Wyland Jul 09 '11 at 23:05
  • Ok, I found response.isCommitted() is a way to determine if the headers have already been written. The response is NOT yet committed so it should still be open to the redirect. – Kenny Wyland Jul 09 '11 at 23:10

2 Answers2

12

The <jsp:include> uses under the covers RequestDispatcher#include(). Click the link to see the javadoc. Here's an extract of relevance (emphasis mine):

...

The ServletResponse object has its path elements and parameters remain unchanged from the caller's. The included servlet cannot change the response status code or set headers; any attempt to make a change is ignored.

...

The HttpServletResponse#sendRedirect() basically sets the HTTP response status to 302 and the HTTP Location header to the target URL. It is thus totally being ignored.

The deeper problem is that you're abusing JSP as a page controller/filter. You should actually be using a normal servlet or filter class for this which runs far before JSP.

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • I totally agree about the abuse, unfortunately I'm required to fit within some very strict boundaries. Thank you for the doc snippet above, I had no idea. – Kenny Wyland Jul 11 '11 at 17:57
0

The redirect header (I believe) needs to be at the top of the page. View the HTML spec for reference.

Have you tried placing it at the very top of the page? A code sample would help us debug...

WattsInABox
  • 4,548
  • 2
  • 33
  • 43
  • Unfortunately, I can't provide much in the way of code snippets due to privacy concerns for my client. It's a fairly complex site with multiple levels of jsp:includes and such. – Kenny Wyland Jul 09 '11 at 23:01
  • I have verified that no status code or other headers have been sent at the time when I'm trying to redirect, so it is effectively at the "top of the page." – Kenny Wyland Jul 09 '11 at 23:09