Download (direct link):
¦¦ The URL class is conceptually overloaded. A URL is merely an abstraction for an address or an endpoint. In fact, it would be better to have URL subclasses to differentiate static resources from dynamic services. What is missing conceptually is a URLClient class that uses the URL as the endpoint to read from or write to.
¦¦ The URL class is biased toward retrieving data from a URL. There are three methods you can use to retrieve content from a URL and only one way to write data to a URL. This disparity would be better served with a URL subclass for static resources that only has a read operation. The URL subclass for dynamic services would have both read and write methods. That would provide a clean conceptual model for use.
¦¦ The naming of the protocol handlers "stream" handlers is confusing because their primary purpose is to generate (or build) a connection. A better model to follow would be the one used in the Java API for XML Parsing (JAXP) where a DocumentBuilderFactory produces a DocumentBuilder that produces a Document. Applying that model to the URL classes would yield a URLCon-nectorFactory that produces a URLConnector that produces a URLConnection.
Now that we have the general picture, we are ready to tackle the URLConnection class and attempt to post to a URL. Our goal is to create a simple Java program that posts some text to a Common Gateway Interface (CGI) program. To test our programs, I created a simple CGI program in C that echoes (in an HTML wrapper) whatever is passed in to it. Listing 17.1 is the source code for that CGI program called echocgi.c.
7 Norman, Donald A., The Design of Everyday Things, Doubleday, 1988, page 13.
128 Item 17
URLConnection openConnection() InputStream openStream()
URLStreamHandler createURLStreamHandler(String protocol)
URLConnection openConnection(URL u)
creates per connection
void setRequestProperty(string p, string v) InputStream getInputStream() OutputStream getOutputStream() ContentHandler getContentHandler() Object getContent()
sun.net.www.protocol.ftp.Handler | sun.net.www.protocol.jar.Handler | sun.net.www.protocol.http.Handler |
HttpURLConnection JarURLConnection ContentHandler
Object getContent(URLConnection urlc)
HttpURLConnection JarURLConnection jpe9 Plain
Figure 17.1 URL Classes in the java.net package.
01 #include <stdio.h>
02 #include <stdlib.h>
03 #include <string.h>
05 void main(int argc, char **argv)
07 char *request_method = NULL;
08 char *content_length = NULL;
09 char *content_type = NULL;
10 int length=0;
11 char *content = NULL;
12 int read = 0;
Listing 17.1 echocgi.c
When Posting to a URL Won't 129
14 /* get the key environment variables. */
15 request _method = getenv("REQUEST_METHOD");
16 if (!request_method)
18 printf("Not being run as a CGI program.\n");
22 // set outgoing content type
23 printf( "Content-type: text/html\n\n");
25 if (strcmp(request_method, "POST") == 0)
27 content_length = getenv("CONTENT_LENGTH");
28 content_type = getenv("CONTENT_TYPE");
30 length = atoi(content_length);
31 if (length > 0)
33 content = (char *) malloc(length + 1);
34 read = fread(content, 1, length, stdin);
35 content[length] = '\0'; /* NUL terminate */
39 printf("<TITLE> Echo CGI program </TITLE>\n");
41 printf("<BODY BGCOLOR='#ebebeb'>");
43 printf("<H2> Echo </H2>\n");
45 if (length > 0)
47 printf("Length of content: %d\n", length);
48 printf("Content: %s\n", content);
51 printf("No content! ERROR!\n");
57 // print out HTML error
58 printf("<HTML> <HEAD> <TITLE> Configuration Error ^
59 printf("<BODY> Unable to run the Echo CGI Program. <BR>\n");
60 printf("Reason: This program only tests a POST method. ^
Listing 17.1 (continued)
130 Item 17
61 printf("Report this to your System Administrator. </BR>\n");
62 printf("</BODY> </HTML>\n");
Listing 17.1 (continued)
Testing the CGI program requires two things: a Web server and a browser or program to post information to the program. For the Web server, I downloaded and installed the Apache Web server from www.apache.org. Figure 17.2 displays the simple HTML form used to post information (two fields) to the CGI program. When the "Submit your vote" button is clicked in the HTML form, the two values are posted to the CGI program (on the localhost) and the response page is generated as is shown in Figure 17.3.
Now that we have a simple CGI program to echo data posted to it, we are ready to write our Java program to post data. To send data to a URL, we would expect it to be as easy as writing data to a socket. Fortunately, by examining the URLConnection class we see that it has getOutputStream() and getInputStream() methods, just like the Socket class. Armed with that information and an understanding of the HTTP protocol, we write the program in Listing 17.2, BadURLPost.java.