I am trying to understand the difference between addHeader and setHeader. Could anyone please put more light on this. The difference I know is that setHeader overwrites existing value where as addHeader adds an additional value to existing header. Here is the sample servlet code I wrote to experiment:
Now, to verify what all headers are actually coming in response, I wrote following code:
Here is the output I got:
Key = [h2] Value = [h2-v3,h2-v2,h2-v1] Key = [Content-Length] Value =  Key = [h1] Value = [v3,v2,new v1] Key = [Date] Value = [Tue, 19 Apr 2005 02:00:52 GMT] Key = [Server] Value = [Apache-Coyote/1.1] Key = [null] Value = [HTTP/1.1 200 OK]
Could anyone please explain me values returned for "h1" header?
Appreciate very much.
SCWCD 1.4<br />---------------------<br />Ability is what you're capable of. <br />Motivation determines what you do. <br />Attitude determines how well you do it.<br />---------------------
addHeader - simply adds the header to the response( doesn't overwrite the existing ones..) setHeader - clears all the existing ones( i.e with same header name) and adds the header to the response...
Joined: May 28, 2004
I understand the distinction between addHeader() and setHeader(), which is why I also don't understand the behavior observed. Shouldn't the "h1" header be "new v1" only (instead of a "new v1", "v2" and "v3")? Instead of overwriting the "h1" header values entirely, it appears to replace just the first of the three values. I added another setHeader() to the example, and again, it only overwrote the first "h1" header value:
Got this back in the headers:
h1: yet again, v2, v3
Doesn't seem right, at least as far as I understand it.
Why don't you use the following code (from Tomcat 5.5) to retrieve headers?
[ April 19, 2005: Message edited by: Rafael Pereira ]
Sun Certified Web Component Developer 1.4<br />Linux LPI Certified (LPIC-1)<br />Sun Certified Java Programmer 1.4
Joined: May 28, 2004
I guess I still don't understand the distinction being made. For reference, I did not use the URLConnection API (at least directly) like Anand did, but I'm not understanding the difference. I was using the Live HTTP Header plug-in for FireFox to snoop on the headers; I don't know what underlying plumbing is used to return those values, but I doubt it is the URLConnection API, or that it's written in Java at all, but who knows?
Regardless of the mechanism used to capture the HTTP headers returned from the servlet, I still don't understand why the original values of the "h1" header are not being discarded when setHeader() is used. I look at it as if the header values are being maintained in a ArrayList.
When addHeader(name, value) is used, it's comparable to the following ArrayList method:
That I understand.
But when setHeader(name, value) is called, we get behavior like:
where the value replaces the current value at the 0 index location in the ArrayList, but does not clear the contents of the subsequent locations.
My expectation, from reading HFS, is that we would get the results comparable to the following:
When I say setHeader("h1", "new test"), my expectation is that the ONLY value for the "h1" header is now "new test". But that's not what I'm seeing.
Joined: Mar 21, 2005
Sorry guys to check out your replies so late, I am keeping busy in synchronizing work pressure, theory reading from HFS book, doing hands on to learn more & more and preparing notes too so that I can submit / publish to help other ceritifcation-doers.
For this problem, it's still open! I agree with Todd's explaination to my problem/understanding given by him very well. From Todd's addition, seems like setHeader replaces only first value of the header (replacing only first element of arraylist). is that correct and be verified from somewhere? Thank you very much Todd for your effort.
Chowdary, could you please put some more light on servlets/http/RFC specs and URLConnection APIs. In my understanding the underlying implementation of URLConnection is Socket and I would expect it to comply with servlets/HTTP/RFC specs. I will further try to use Apache provided HttpClient API also, and will also try the firefox pplugin to see header values, but somehow I am afraid, that I would still get the same result as given by firefox plugin as suggested by Todd. Also, please advise what header-snooper you would use.
I am wondering if there is any resource like JLS ?? I would browse through Servlet Specs once again for this.
I am using Tomcat 5.0 and JDK 1.4 (URLConnection, only 1.4/later supports getHeaderFields() method)
Rafael, I am interested in traversing headers sent in response, not the headers received in request object.
Anyone, find anything, please reply, I highly appreciate people effort / time spending on solving this. Thank you very much.
[ April 19, 2005: Message edited by: Anand Wadhwani ] [ April 19, 2005: Message edited by: Anand Wadhwani ]
Joined: Aug 16, 2004
Hai Anand I was also kicking myself to get an answer to your question.
I totally agree with your previous post. My earlier posts were S... well you know what.
The Servlet API Javadocs for HttpServletResponse's setHeader() method says that
"Sets a response header with the given name and value. If the header had already been set, the new value overwrites the previous one."
Overwrites, which "previous one" is ambiguous too. Is the value that has been set by a previous setHeader() method overwritten or the value set by the first addHeader() method overwritten.
I thought may be a step by step testing of the program could lead me somewhere. I got these results so far (with changes to your program).
the result was
This is pretty well expected.
But if i add an addHeader() method in between the two see what happens, for the following code
The result is C:\>java HeaderTest Key = [h2] Value = [add two,set one] Key = [Content-Length] Value =  Key = [h1] Value = [add another value to the header,overwrite previous] Key = [Date] Value = [Wed, 20 Apr 2005 05:15:01 GMT] Key = [Server] Value = [Apache-Coyote/1.1] Key = [null] Value = [HTTP/1.1 200 OK]
So I agree with Todd over this. Only the first value to be set is being overwritten by using a setHeader for a header which already has multiple values.
Neither the API nor the specs warn you about using a setHeader after using an addHeader. The docs for addHeader just inform that this method makes it possible for a header to have multiple values.
So this may be the expected behavior. I'm trying to go through the tomcat code to see if I can find something. All I see so far is calls to coyoteResponse.setHeader() and coyoteResponse.addHeader(). I'm hunting for the coyoteResponse thing.
Joined: Aug 16, 2004
I'm trying to go through the Tomcat source code and found the following thing interesting.
In both TOMCAT Source version 5.5.7 and version 5.5.9
The public final class Response in package org.apache.coyote
has a protected "headers" field which is of type 'an array of MimeHeaders'.
and this class delegates calls to setHeader() as follows
[checkSpecialHeader() checks if the header being set is Content-lenght or Content-type and makes sure only one header value exists]
After this, the difference is
In 5.5.7 the code for MimeHeaders.setValue() which is a class in org.apache.tomcat.util.http package is as follows
But in Tomcat version 5.5.9 the same method in the same class in the same package is implemented as follows
I checked what exactly the getValue() method does
It does the following
returns only the First Value as Todd mentioned previously.
Which eaxact version were you guys testing this one on.
IS IT 5.5.7 like me or an earlier version (Please dont say 5.X)
I've not tested it on 5.5.9. It'll be a few days before I change to 5.5.9
Can anybody test this on 5.5.9? Pleeeeease [ April 20, 2005: Message edited by: chowdary Thammineedi ]
Joined: Aug 16, 2004
I Just changed my Tomcat version to 5.5.9 from 5.5.7 and the result was PERFECT.
For the same program you mentioned at the top of this thread, the output was
Now that explains the difference b/w version 5.5.7 and 5.5.9. Doesn't it?
Hey chowdary! Thanks very muchh!!! All crystal Clear... check-mate ! Appreciate your tremendous effort in digging out and resolving the issue.
I am wondering, if any such question (with code exhibit) comes in exam, what answer would I give. I shoould not regard to tomcat bug, and I should answer to what setHeader is supposed to do, overwrite existing value(s).
Thanks to you & Todd for all your help. [ April 22, 2005: Message edited by: Anand Wadhwani ]
Joined: Aug 16, 2004
That's exactly right.
setHeader() clears all values of a header that have been previously set and sets it to the new value.
This is what we MUST follow for the exam. [ April 21, 2005: Message edited by: chowdary Thammineedi ]