wood burning stoves*
The moose likes Web Component Certification (SCWCD/OCPJWCD) and the fly likes addHeader VS setHeader Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Android Security Essentials Live Lessons this week in the Android forum!
JavaRanch » Java Forums » Certification » Web Component Certification (SCWCD/OCPJWCD)
Bookmark "addHeader VS setHeader" Watch "addHeader VS setHeader" New topic
Author

addHeader VS setHeader

Anand Wadhwani
Ranch Hand

Joined: Mar 21, 2005
Posts: 151
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 = [0]
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.


Anand
SCJP1.4


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 />---------------------
chowdary Thammineedi
Ranch Hand

Joined: Aug 16, 2004
Posts: 126
Anand
Can you please tell us the servlet container on which you ran this program.

Thank you
Todd Farmer
Ranch Hand

Joined: May 28, 2004
Posts: 59
I don't know about Anand, but I am using Tomcat 5.0 and getting the same results. Interesting!

Todd Farmer
SCJP
Praveen Kumar Mathaley
Ranch Hand

Joined: Apr 14, 2003
Posts: 45
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...
Todd Farmer
Ranch Hand

Joined: May 28, 2004
Posts: 59
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.

Todd Farmer
Rafael Pereira
Ranch Hand

Joined: Mar 23, 2005
Posts: 32
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
Todd Farmer
Ranch Hand

Joined: May 28, 2004
Posts: 59
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:

ArrayList.add(value)

That I understand.

But when setHeader(name, value) is called, we get behavior like:

ArrayList.set(0, value)

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:

ArrayList.clear();
ArrayList.add(value);

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.

Todd Farmer
Anand Wadhwani
Ranch Hand

Joined: Mar 21, 2005
Posts: 151
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 ]
chowdary Thammineedi
Ranch Hand

Joined: Aug 16, 2004
Posts: 126
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 = [0]
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.
chowdary Thammineedi
Ranch Hand

Joined: Aug 16, 2004
Posts: 126
Hello Anand

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 ]
chowdary Thammineedi
Ranch Hand

Joined: Aug 16, 2004
Posts: 126
Hello Anand

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?

Also note the order of the [h2] header values.
chowdary Thammineedi
Ranch Hand

Joined: Aug 16, 2004
Posts: 126
This is a bug in Tomcat upto versions 5.5.8

More info here.
http://issues.apache.org/bugzilla/show_bug.cgi?id=34113

It has been fixed for version 5.5.9
Anand Wadhwani
Ranch Hand

Joined: Mar 21, 2005
Posts: 151
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 ]
chowdary Thammineedi
Ranch Hand

Joined: Aug 16, 2004
Posts: 126
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 ]
 
It is sorta covered in the JavaRanch Style Guide.
 
subject: addHeader VS setHeader
 
Similar Threads
sorting
arrayOutOfIndex
Response Headers
Help please
doubt on response.addHeader