Is there a way to iterate through HttpServletRequest.getAttributeNames() more than once?
Asked Answered
M

1

10

I'm trying to log the contents of the HttpServletRequest attributes collection. I need to do this when the servlet first starts, and again right before the servlet is finished. I'm doing this in an attempt to understand a crufty and ill-maintained servlet. Because I need to have as little impact as possible, servlet filters are not an option.

So here's the problem. When the servlet starts, I'll iterate through the enumeration returned by HttpServletRequest.getAttributeNames(). However, when I want to iterate through it again, getAttributeNames().hasMoreElements() returns "false"! I can't find any way to "reset" the enumeration. What's worse is that, even if I add attributes to the collection using HttpServletRequest.setAttribute(), I still get a result of "false" when I call getAttributeNames().hasMoreElements().

Is this really possible? Is there really no way to iterate through the attribute names more than once?

By request, here's my code. It's pretty straightforward -- don't think I'm doing any funny stuff.

/**
 * 
 * Returns the contents of the Attributes collection, formatted for the InterfaceTracker loglines
 * 
 */
@SuppressWarnings("unchecked")
public static String getAttributes(HttpServletRequest request) {
    try {       
        StringBuilder toLog = new StringBuilder();  

        Enumeration attributeNames = request.getAttributeNames();           

        while(attributeNames.hasMoreElements()) {
            String current = (String) attributeNames.nextElement();

            toLog.append(current + "=" + request.getAttribute(current));            

            if(attributeNames.hasMoreElements()) {
                toLog.append(", ");
            }           
        }       

        return "TRACKER_ATTRIBUTES={"+ toLog.toString() + "}";
    }
    catch (Exception ex) {
        return "TRACKER_ATTRIBUTES={" + InterfaceTrackerValues.DATA_UNKNOWN_EXCEPTION_THROWN + "}";
    }               
}
Margerymarget answered 20/8, 2010 at 16:47 Comment(2)
so you are calling getAttributes method at start of service/doGet/doPost method and then again call it at end, rite ?Annals
Downvoting as this is just a user error.Matriculate
D
22

Perhaps you should post the code where you call HttpServletRequest.setAttribute().

At this point it would seem that your crufty and ill-maintained servlet is removing attributes between your two calls to getAttributeNames(), but without any code samples it's hard to say.

UPDATE

Nothing in your code is jumping out at me as being faulty... so I crafted an extremely simple test case inside handleRequest() and gave it a whirl (using jboss-eap-4.3 as my container). I had to manually set an attribute first, as my understanding of request attributes is they are always set server side (i.e. if I didn't set it then I didn't get any output as the Enumeration returned by getAttributeNames() was empty).

request.setAttribute("muckingwattrs", "Strange");

Enumeration attrs =  request.getAttributeNames();
while(attrs.hasMoreElements()) {
    System.out.println(attrs.nextElement());
}

System.out.println("----------------------------");

Enumeration attrs2 =  request.getAttributeNames();
while(attrs2.hasMoreElements()) {
    System.out.println(attrs2.nextElement());
}

output

INFO  [STDOUT] muckingwattrs
INFO  [STDOUT] ----------------------------
INFO  [STDOUT] muckingwattrs

So perhaps your container doesn't implement getAttributeNames() correctly? Maybe try an extremely simple test case like mine directly in handleRequest() or doGet()/doPost().

Decrepitude answered 20/8, 2010 at 17:9 Comment(4)
Thanks for the help, but I know it isn't the servlet's fault. As a test, I've tried adding attributes to the collection RIGHT AFTER iterating through it, in the very same function. And still, hasMoreElements() comes back false.Margerymarget
maybe you didn't call back getAttributeNames the second time that's why a full sample would be interesting. and more which servlet container do you use?Dominicadominical
Okay, I found my problem. And I feel kinda silly, because the problem had nothing to do with HttpServletRequest. I eventually noticed that I was only getting this problem in my unit test, and not when I actually ran the servlet. Turns out, I was using Mockito wrong. So even though you had no way of finding the root cause of my problem, you did help me eliminate HttpServletRequest as a possibility. So thanks!Margerymarget
Isn't that usually how it goes? :) Glad we could help (even if indirectly)!Decrepitude

© 2022 - 2024 — McMap. All rights reserved.