Link to home
Start Free TrialLog in
Avatar of loopyadc
loopyadc

asked on

session.removeAttribute at END of JSP is causing use of the session object in the MIDDLE to fail

Hi

I am setting a session object called errors within a Struts backend Action. A servlet for those who don't use Struts. My action then forwards to a JSP. This JSP is included by a master layout JSP, and in the middle if it detects the errors object in the session it iterates over it. At the end of the page I need to make sure that the errors object is gone but not other session objects, so I use the session.removeAttribute method.

I have determined that placing this removeAttribute call anywhere in the JSP including not only at the end, but also in the master template JSP that includes this current JSP causes the errors object to nullify and it cannot be iterated over!!

My question is how on earth can I use the object and then get rid of it before the next request? I do not want to get rid of it ON the next request but at the END of processing the error showing JSP.

And by the way I cannot use the request scope ... I need the session in this particular case because of an IIS bug I am working around.

Cheers, ADC
Avatar of jarasa
jarasa
Flag of Spain image

Put a boolean attribute on your session and set it to true, then in the next JSP ask for it if is true remove the error attribute.

That makes sense to me :c)

Javier
ASKER CERTIFIED SOLUTION
Avatar of searlas
searlas

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of searlas
searlas

Sorry, didn't read the IIS bug bit...

Can you show us stripped-down-code exhibitting the problem?
Searlas have you read this part?

>And by the way I cannot use the request scope ... I need the session in this particular case because of an IIS bug >I am working around.

Javier
;c) I knew you didn't
Avatar of loopyadc

ASKER

I can try but it's a huge page..

at the very bottom of the JSP is

<%
    session.removeAttribute("errors");
    session.removeAttribute("errorListSession");
    session.removeAttribute("isNotValid");
    session.removeAttribute("isCheckinNewVersion");
    session.removeAttribute("isUpdate");        
%>

at the very top is

      org.apache.struts.action.ActionErrors errors = null;

      if (! isUpdate) {
            errors = (org.apache.struts.action.ActionErrors) session.getAttribute("errors");
            if (errors != null) {      
                  out.println("found errors");            
                  request.setAttribute(org.apache.struts.action.Action.ERROR_KEY, errors);
            }
      } else {
            errors = (org.apache.struts.action.ActionErrors) request.getAttribute("errors");
      }

and in the very middle

      <%            
            if (errors != null) { %>
                  
                  <logic:messagesPresent>
                        <ul>
                        <html:messages bundle="APPLICATION_RESOURCES" id="error">
                              <li class="error_list"><bean:write name="error" /></li>
                        </html:messages>
                        </ul>
                  </logic:messagesPresent>
                  <%
            }
      %>

and in between all that lots of code!

I could try the boolean is session idea...
nope :( the trouble is that the "next page" does not really exist since all my JSPs are built using tile templates. That is, the page with the error is itself the same as the other pages and so if I put this boolean flag up in the master template then even when i DO want the errors to come up on the JSP in question it will also notice to remove the attributes if you see what I mean?

I tried it and it didn't work because of this....why can it not recognise the sequence? Are JSPs not processed in top down fashion!?
JSPs is processed in top down. Do you mean when you put session.removeAttribute("errors") anywhere in the code will cause  (org.apache.struts.action.ActionErrors) session.getAttribute("errors"); return null ?

That's strange. Maybe you can check whether you have any other removeAttribute("errors") method called some where in your code ?
         
yes, I can put the session.removeAttribute("errors") anywhere in this JSP and that nullifies it!! If it were top down then I would expect what I have done by placing the removal at the end to work.
OK, you said you can't put the errors object in the request, so why does this code exist?
if (! isUpdate) {
          errors = (org.apache.struts.action.ActionErrors) session.getAttribute("errors");
          if (errors != null) {    
               out.println("found errors");          
               request.setAttribute(org.apache.struts.action.Action.ERROR_KEY, errors);
          }
} else {
          errors = (org.apache.struts.action.ActionErrors) request.getAttribute("errors");
}


Have you tried putting the removeAttribute call here:
if (! isUpdate) {
  errors = (org.apache.struts.action.ActionErrors) session.getAttribute("errors");
  System.out.println("errors: " + errors);
  session.removeAttribute("errors");
  System.out.println("after removeAttribute, errors: " + errors);

because I call an include that spits out using struts bean tags the error messages linked to labels in a properties file. So that I can use that same code, I transfer from the session into the request.

The backend cannot use the request because it is a redirect to this page and we cannot get around this due to a upload stream bug in the JK2 ISAPI IIS module, so we use the session instead to get over the redirect.

But for code reuse, that is why I transfer it into the request. However, that never gets called because by this time it is null simply because removeAttr at the end of that JSP is present.

Ridiculous, highly irritating, illogical ;) and is going to be a show stopper for our release this weekend.

HELP! :))
That would be this bit:
<%          
          if (errors != null) { %>
               
               <logic:messagesPresent>
                    <ul>
                    <html:messages bundle="APPLICATION_RESOURCES" id="error">
                         <li class="error_list"><bean:write name="error" /></li>
                    </html:messages>
                    </ul>
               </logic:messagesPresent>
               <%
          }
     %>

Why the guard with "if (errors != null)..."  Isn't that the entire point of logic:messagesPresent?

Regardless.  Whenever I get unexpected behavior I always strip down pages to the bare
minimum, or alternatively code up a test page.  If it's possible to temporarily replace the JSP
to do some testing I'd create a simple JSP that just does this:

version 1:
<%= session.getAttribute("errors") %>

version 2:
<%= session.getAttribute("errors") %>
<% session.removeAttribute("errors"); %>

And if version 2 is still showing you what you expect, then you know you've got a problem
with your original JSP.
Have you got the .java file your jsp was translated into?  If so, I'd have a look at that
to see where the removeAttribute("errors") call lies in relation to your other calls...
none of the comments worked I'm afraid. I solved the problem by solving the problem that was forcing me to do this horrid session based strategy, so I ended up using the right object for this sort of thing which is request.
I'm afraid not no, nice try.

If you read the end of my original question I said "And by the way I cannot use the request scope ... I need the session in this particular case because of an IIS bug I am working around."

and you said

"Set the errrors collection on the request instead of the session.  It will be available for use by your JSP, and then you can forget about it."

Now that looks to me like you did not read my question :) I am quite aware of the varoius scopes within J2EE development. I had a particular problem that meant using the session.

My solution came because the vendor of the upload utility I am using released a new version with the bug fixed, so I did not have to continue with all this session rubbish and could do it the correct way using the request, which I was always aware was the correct way but I did state in my original question that I could not use it.

Cheers :)
However Searlas, since you put a lot of effort in subsequent answers into this question I have decided you should be awarded points anyway. I'm feeling nice today ;)
I not that searlas does not worth the ponits loopyadc but you shouldn't award point to a non valid answer.

Anyway is too late, but this is suppose to help others to find answers so the questions should have one.

Javier
jarasa, I see your point, but the solution stands.  I think the original question was misleading as "an IIS bug" was somehow fixed "because the vendor of the upload utility I am using released a new version with the bug fixed".  Unless that vendor was Microsoft, I don't see how they've fixed a bug in IIS.

As for diagnosing the problem using the session, there wasn't any response to this comment
https://www.experts-exchange.com/questions/20946286/session-removeAttribute-at-END-of-JSP-is-causing-use-of-the-session-object-in-the-MIDDLE-to-fail.html#10781704

... had there been, I'm confident we could have continued and found the cause for the perceived problem with session.removeAttribute...
i was aware of that but the answer I accepted was in fact the correct way of doing it afterall.

The end solution was to use the request scope, and therefore this is still a valid accepted answer.

The upload item was Jakarta JK2 IIS ISAPI filter was terminating an upload stream unexpectedly. Jakarta project fixed this in 2.0.4.
:c)