In HTTP 1.0 and later, the client sends the server not only a request line, but also a header. For example, here's the HTTP header that Wamcom Mozilla 1.3 for Mac OS uses:
Host: stallion.elharo.com:33119 User-Agent: Mozilla/5.0 (Macintosh; U; PPC; en-US; rv:1.3.1) Gecko/20030723 wamcom.org Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/ plain;q=0.8,video/x-mng,image/png,image/jpeg,image/gif;q=0.2,*/*;q=0.1 Accept-Language: en-us Accept-Encoding: gzip,deflate Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7 Connection: close
A web server can use this information to serve different pages to different clients , to get and set cookies, to authenticate users through passwords, and more. Placing different fields in the header that the client sends and the server responds with does all of this.
| || |
It's important to understand that this is not the HTTP header that the server sends to the client and that it is read by the various getHeaderField( ) and getHeaderFieldKey() methods discussed previously. This is the HTTP header that the client sends to the server .
Each concrete subclass of URLConnection sets a number of different name -value pairs in the header by default. (Really, only HttpURLConnection does this, since HTTP is the only major protocol that uses headers in this way.) For instance, here's the HTTP header that a connection from the SourceViewer2 program of Example 15-1 sends:
User-Agent: Java/1.4.2_05 Host: localhost:33122 Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2 Connection: keep-alive
As you can see, it's a little simpler than the one Mozilla sends, and it has a different user agent and accepts different kinds of files. However, you can modify these and add new fields before connecting.
In Java 1.3 and later, you can add headers to the HTTP header using the setRequestProperty() method before you open the connection:
public void setRequestProperty(String name, String value)// Java 1.3
The setRequestProperty( ) method adds a field to the header of this URLConnection with a specified name and value. This method can be used only before the connection is opened. It throws an IllegalStateException ( IllegalAccessError in Java 1.3) if the connection is already open. The getRequestProperty() method returns the value of the named field of the HTTP header used by this URLConnection .
HTTP allows one property to have multiple values. In this case, the separate values will be separated by commas. For example, the Accept header sent by Java 1.4.2 shown above has the four values text/html, image/gif, image/jpeg, and *.
| || |
These methods only really have meaning when the URL being connected to is an http URL, since only the HTTP protocol makes use of headers like this. While they could possibly have other meanings in other protocols, such as NNTP, this is really just an example of poor API design. These methods should be part of the more specific HttpURLConnection class, not the generic URLConnection class.
For example, web servers and clients store some limited persistent information by using cookies. A cookie is simply a name-value pair. The server sends a cookie to a client using the response HTTP header. From that point forward, whenever the client requests a URL from that server, it includes a Cookie field in the HTTP request header that looks like this:
Cookie: username=elharo; password=ACD0X9F23JJJn6G; session=100678945
This particular Cookie field sends three name-value pairs to the server. There's no limit to the number of name-value pairs that can be included in any one cookie. Given a URLConnection object uc , you could add this cookie to the connection, like this:
uc.setRequestProperty("Cookie", "username=elharo; password=ACD0X9F23JJJn6G; session=100678945");
The setRequestProperty() method does not support this. You can set the same property to a new value, but this changes the existing property value. To add an additional property value, use the addRequestProperty() method instead:
public void addRequestProperty(String name, String value)// Java 1.4
There's no fixed list of legal headers. Servers will typically ignore any headers they don't recognize. HTTP does put some restrictions on the content of the names and values here. For instance, the names can't contain whitespace and the values can't contain any line breaks. Java enforces the restrictions on fields containing line breaks, but not much else. If a field contains a line break, setRequestProperty() and addRequestProperty( ) throw an IllegalArgumentException . Otherwise, it's quite easy to make a URLConnection send malformed headers to the server, so be careful. Some servers will handle the malformed headers gracefully. Some will ignore the bad header and return the requested document anyway, but some will reply with an HTTP 400, Bad Request error.
If for some reason you need to inspect the headers in a URLConnection , there's a standard getter method:
public String getRequestProperty(String name)// Java 1.3
Java 1.4 also adds a method to get all the request properties for a connection as a Map :
public Map getRequestProperties( ) // Java 1.4
The keys are the header field names. The values are lists of property values. Both names and values are stored as strings. In other words, using Java 1.5 generic syntax, the signature is:
public Map<String,List<String>> getRequestProperties( )