Recommended: Sing it, brah! 5 fabulous songs for developers
JW's Top 5
Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs
Page 2 of 6
URL class is conceptually overloaded. A URL is merely an abstraction for an address or an endpoint. In fact, a better design
would feature URL subclasses that differentiate static resources from dynamic services. Missing conceptually is a URLClient class that uses the URL as the endpoint to read from or write to.
URL class is biased toward retrieving data from a URL. There are three methods that retrieve content from a URL, but only one
that writes data to a URL. That 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 design would provide a
clean conceptual model for use.
DocumentBuilderFactory produces a DocumentBuilder, which produces a Document. Applying that model to the URL classes would yield a URLConnectorFactory that generates a URLConnector that produces a URLConnection.
Now you are ready to tackle the URLConnection class and attempt to post to a URL. The goal is to create a simple Java program that posts some text to a common gateway
interface (CGI) program. To test the programs, I created a simple CGI program in C that echoes (in an HTML wrapper) whatever
passes into it. (See Resources to download the source code for any program in this article, including the CGI program.)
The URLConnection class has getOutputStream() and getInputStream() methods, just like the Socket class. Based on that similarity, you would expect that sending data to a URL would be as easy as writing data to a Socket. Armed with that information and an understanding of the HTTP protocol, we write the program in Listing 5.1, BadURLPost.java.
Listing 5.1 BadURLPost.java
package com.javaworld.jpitfalls.article3;
import java.net.*;
import java.io.*;
public class BadURLPost
{
public static void main(String args[])
{
// get an HTTP connection to POST to
if (args.length < 1)
{
System.out.println("USAGE: java GOV.dia.mditds.util.BadURLPost
url");
System.exit(1);
}
try
{
// get the url as a string
String surl = args[0];
URL url = new URL(surl);
URLConnection con = url.openConnection();
System.out.println("Received a : " + con.getClass().getName());
con.setDoInput(true);
con.setDoOutput(true);
con.setUseCaches(false);
String msg = "Hi HTTP SERVER! Just a quick hello!";
con.setRequestProperty("CONTENT_LENGTH", "5"); // Not checked
con.setRequestProperty("Stupid", "Nonsense");
System.out.println("Getting an input stream...");
InputStream is = con.getInputStream();
System.out.println("Getting an output stream...");
OutputStream os = con.getOutputStream();
/*
con.setRequestProperty("CONTENT_LENGTH", "" + msg.length());
Illegal access error - can't reset method.
*/
OutputStreamWriter osw = new OutputStreamWriter(os);
osw.write(msg);
osw.flush();
osw.close();
System.out.println("After flushing output stream. ");
// any response?
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line = null;
while ( (line = br.readLine()) != null)
{
System.out.println("line: " + line);
}
} catch (Throwable t)
{
t.printStackTrace();
}
}
}
A run of Listing 5.1 produces: