views:

105

answers:

3

Hi,

How do you stop a JSP from executing?

I have JSPs which kick the user off a page by means of a "forward".

public boolean kickIfNotLoggedIn(
        HttpServletRequest request, HttpServletResponse response)
        throws IOException, ServletException {
    //code to check if user is logged in
    req.getRequestDispatcher(
            ACCESS_DENIED_PAGE).forward(request, response);
}

In my JSP, I have this code, BEFORE any HTML output:

<%
            //loginHelper.kickIfNotLoggedIn(request, response);
            if (!loginHelper.kickIfNotLoggedIn(request, response)) {
                return;
            }
%>

If I don't use the return statement, the JSP continues processing, and I get a NullPointerException. If I use the return statement (as is commonly suggested on various sources on the net), I get an IllegalStateException:

StandardWrapperValve[jsp]: PWC1406: Servlet.service() for servlet jsp threw exception
java.lang.IllegalStateException: PWC3991: getOutputStream() has already been called for this response
        at org.apache.coyote.tomcat5.CoyoteResponse.getWriter(CoyoteResponse.java:717)
        at org.apache.coyote.tomcat5.CoyoteResponseFacade.getWriter(CoyoteResponseFacade.java:226)
        at org.apache.jasper.runtime.JspWriterImpl.initOut(JspWriterImpl.java:187)

Any ideas how to fix this, or another way to achieve an access denied page?

Thanks

+2  A: 

You can't do it this way. The error message is a bit unclear but it has to do with starting rendering a response in one resource, stopping, then forwarding on to another resource which tries to restart processing of the HTTP response.

Use a servlet Filter instead, in front of all JSPs that need login, to redirect before any JSP even touches the response.

Sean Owen
@Sean Owen: Thanks for the answer, could you point me in the direction of how to go about creating a Servlet Filter for my JSPs? Much appreciated.
bguiz
@bguiz: http://courses.coreservlets.com/Course-Materials/msajsp.html
BalusC
@BalusC : Thanks, that was a really good set of articles you linked!
bguiz
A: 

Use:

req.getRequestDispatcher(ACCESS_DENIED_PAGE).redirect(request, response);

Make sure your call to check permissions is the first thing in a page to avoid that error message.

The "right" way is of course a filter but it might be too involved for what you need. In any case look here:

http://java.sun.com/products/servlet/Filters.html
Toader Mihai Claudiu
A: 

One annoying thing about JSP is that any space will cause the OutputStream to be fetched (at least in tomcat). So for example the following code will fail:

<%@ page import="javax.servlet.ServletOutputStream" %>

<%
  //note the blank line above^
  ServletOutputStream out = response.getOutputStream();
  //write some data...
%>

as the blank line between the import and the code block is considered by tomcat to be part of the output, so it will get the writer and output two new lines. So to work you need to make sure there are no extraneous characters in the code:

<%@ page import="javax.servlet.ServletOutputStream" %><%
  //no blank line, this will work OK
  ServletOutputStream out = response.getOutputStream();
  //write some data...
%>

now there are no characters between the code blocks so tomcat will not try to generate output. My guess is this is the reason for your exception. That said this is more a quick and dirty fix, and something like what Sean has suggested is likely a more appropriate solution.

M. Jessup
It's not annoying. It's just abuse of JSP. JSP is a view technology, not a controller or a filter.
BalusC