#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2003
    Posts
    13
    Rep Power
    0

    response.encodeURL() & Block All Cookies


    Hello All,

    My understanding of encodeURL() is that it is supposed to negate the issue of a browser having cookies switched off. However, despite running all of my HREF URLs through it, after switching off cookies in my browser, I'm getting a;

    java.lang.IllegalStateException: getOutputStream() has already been called for this response
    ---------------------------------------

    As Background, I'm trying to avoid the issue where if someone tries to enter the site via any URL other than the home URL, they are sent to a home servlet to set up a session & a session "status" which then forwards them on again to the main frameset. I achieve this via the following code at the top of each jsp which loads in the 'mainbody' frame.

    <%if (request.getSession(false) == null || request.getSession(false).getAttribute("status") == null)
    {
    request.getRequestDispatcher(response.encodeURL("/clubHome"))
    .forward(request, response);
    }%>
    I have also tried a <jsp:forward...../>

    However, as soon as I turn cookies off, it appears the if() is being executed on 2nd pass through and sending it back to the servlet again, hence the error.

    If someone could point out to me what I'm overlooking please, I'd be grateful. Is there some basic fundamental session context I appear to have missed?

    thanks
  2. #2
  3. No Profile Picture
    Clueless llama
    Devshed Regular (2000 - 2499 posts)

    Join Date
    Feb 2001
    Location
    Lincoln, NE. USA
    Posts
    2,353
    Rep Power
    117
    We need to see all of the servlets code and the jsp you are calling to check the users status in their entirety please.
  4. #3
  5. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2003
    Posts
    13
    Rep Power
    0
    Ok,

    But firstly allow me to apologise for
    no indenting. I haven't yet figured out what makes this board's software tick

    the majority of the code is not relevant. But the relevant servlet code is;

    public void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException
    {
    //If they've been in before, no point in making them do it all over again
    if(request.getSession(false) != null
    && request.getSession(false).getAttribute("status") != null
    && request.isRequestedSessionIdValid())
    {
    // So forward them straight back to the main Frameset
    request.getRequestDispatcher(response.encodeURL("/main.html"))
    .forward(request, response);
    }
    //They've not been in before so let's go through the motions of Setup.
    else
    {
    //-----------------------------------------------------------
    /*DO SOME OTHER dB ACCESS CHECKING HERE*/
    //-----------------------------------------------------------
    // This is necessary as a control variable for the menu sub-page.
    request.getSession().setAttribute("status", Constants.VISITOR);
    //Debugging. Returns 0 (the value of Constants.VISITOR)
    System.err.println("Status = " + (request.getSession(false).getAttribute("status") == null ? "#null": "" + ((Integer) request.getSession(false).getAttribute("status")).intValue()));
    // And send back the main Frameset
    request.getRequestDispatcher(response.encodeURL("/main.html"))
    .forward(request, response);
    //Debugging. Returns A VALID SESSION ID
    System.err.println(request.getSession().getId());
    }

    ============================
    the main Frameset (main.html) looks like;

    <FRAMESET ROWS="140,*" COLS="*" FRAMESPACING="0" FRAMEBORDER="NO" BORDER="0">
    <FRAME SRC="banner.jsp" NAME="_banner" FRAMEBORDER="NO" SCROLLING="NO" NORESIZE TITLE="Banner">
    <FRAME SRC="home.jsp" NAME="_body" FRAMEBORDER="NO" TITLE="Main">
    </FRAMESET>
    ============================
    and the jsp giving the error (home.jsp) looks like;

    <%@ page language="java" import="com.iweb.util.Constants"%>

    <%if (request.getSession(false) == null || request.getSession(false).getAttribute("status") == null)
    {
    // "/clubHome" is mapped to the servlet code as opposed to home.jsp
    request.getRequestDispatcher(response.encodeURL("/clubHome"))
    .forward(request, response);
    }%>

    If I allow cookies, this does the job just dandy, but if I stop them.............

    Funnily enough, if I change "main.html" to "main.jsp", I at least no longer get the nasty stack trace page, rather just a blank white page (like an about:blank URL) in the _body frameset.

    banner.jsp does work because it's not trying to forward anywhere.
  6. #4
  7. No Profile Picture
    Clueless llama
    Devshed Regular (2000 - 2499 posts)

    Join Date
    Feb 2001
    Location
    Lincoln, NE. USA
    Posts
    2,353
    Rep Power
    117
    The reason I wanted to see all your code was that I suspected that you had a problem with your jsp and needed to see how it is exactly. As it is, I think I may know what your problem is. A couple of things - JSP's automatically create a new session for the page, unlike servlets. So checking for a null session like you are doing should never return null. The proper way to supress a jsp from making a session is to use the
    Code:
    <%@ page session="false">
    tag at the top of the page. See here.

    Secondly, the problem with the exception is likely because you are trying to forward to a new page after already outputting to the browser. You cannot have any characters in the jsp before a forward, not even white space (including carriage returns). If this is your actual code
    Code:
    <%@ page language="java" import="com.iweb.util.Constants"%>
    
    <%if (request.getSession(false) == null || request.getSession(false).getAttribute("status") == null) 
    {
    // "/clubHome" is mapped to the servlet code as opposed to home.jsp
    request.getRequestDispatcher(response.encodeURL("/clubHome"))
    .forward(request, response);
    }%>
    The I am guessing the whaite space between the top tag and the scriptlet where you do the forwarding is causing your exception.

    Lastly, you can format code using the ubb code tags. The code tag is like an html tag, except it uses square brackets. [co de]some code here[/co de]
    I put spaces in those so they would not do any formatting.

    From the RequestDispatcher javadocs:
    forward should be called before the response has been committed to the client (before response body output has been flushed). If the response already has been committed, this method throws an IllegalStateException. Uncommitted output in the response buffer is automatically cleared before the forward.
    Last edited by Nemi; April 11th, 2003 at 09:46 PM.
  8. #5
  9. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2003
    Posts
    13
    Rep Power
    0
    Nemi,

    thanks for the reply. There is indeed no space between the page decl. and the if() block. I put that in there for clarity, because I hadn't figured out the [co de] tag (thanks). There is actually another System.err.println in there to try & figure out what's happening.

    I wasn't aware that each page creates it's own session. The JSP syntax pages at Sun say this. I.e. That the page has to join a session, but nothing about creating sessions. I want the jsp page to have to join a session, so how does that fit in?

    Either way however, that doesn't appear to be the problem here. My reasoning is that the 2 err.prinltn()'s in the servlet code tell me that code is being executed twice, which means my if() in the jsp is being executed twice, which in turn means there is no valid session.

    This means it re-forwards back to the servlet again. By this time both jsp & servlet have now been called twice, hence the error.

    I'm a little stumped at the mo. I'll have a further read thru that link, thanks.
  10. #6
  11. No Profile Picture
    Clueless llama
    Devshed Regular (2000 - 2499 posts)

    Join Date
    Feb 2001
    Location
    Lincoln, NE. USA
    Posts
    2,353
    Rep Power
    117
    You still have not posted your code complete. You can also attach files to your post. Maybe you could attach the jsp and the servlet in another post so I could see them?

    I wasn't aware that each page creates it's own session. The JSP syntax pages at Sun say this. I.e. That the page has to join a session, but nothing about creating sessions. I want the jsp page to have to join a session, so how does that fit in?
    You have to realize what the jsp is really doing here. As a convenience, a jsp makes certain variables available by default (pageContext, session, request, response, etc). What it is really doing is making code something like this when it turns your jsp into a servlet:
    Code:
    HttpSession session = request.getSession();
    then it puts that in the pageContext so that the variable is available for you to use throughout the jsp. So, when you call
    Code:
    request.getSession(false) == null
    it will never be null since a request.getSession() has already been called, which makes a new session if one does not exist and assigns it to the request. This make sense? I am not saying this is your problem, I am saying you have code that is not working as you expect and could cause problems for you in the future.

    If you would post your jsp and servlet I would be glad to see if I can help you with your other problem.
    Last edited by Nemi; April 12th, 2003 at 11:27 AM.
  12. #7
  13. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2003
    Posts
    13
    Rep Power
    0
    SORTED!!!!

    Thanks for the effort Nemi. It was a combo of your last 2 posts which eventually led me down the right path.

    The issue was as follows;

    As the code samples I posted show, the main frameset is called 'main.html'; the calling link to home.jsp in the main frameset was simply a call to "home.jsp" with no encodeURL() which basically meant no sessionID was coming into it from the server.

    This would mean, based on what you were saying Nemi, that whilst there might have been a session created (by the jsp itself), the session attribute would always be null, because the session the jsp was creating was not the session coming down from the server and therefore would never contain the appropriate attribute.

    Anyway to cut a long story short; I simply renamed main.html to main.jsp, encodeURL()'ed the calls to the 2 frame body pages and changed the Servlet to forward to main.jsp rather than main.html.

    So they are now being passed the sessionID from the server.

    PHEW! I can enjoy Sat. night now.

IMN logo majestic logo threadwatch logo seochat tools logo