Newsletter sign-up
View all newsletters

Enterprise Java Newsletter
Stay up to date on the latest tutorials and Java community news posted on JavaWorld

Sponsored Links

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

Dodge the traps hiding in the URLConnection class

The URLConnection class's generic design causes snags when posting to a URL

  • Print
  • Feedback

Page 4 of 6

Listing 5.2 BadURLPost1.java

package com.javaworld.jpitfalls.article3;
import java.net.*;
import java.io.*;
public class BadURLPost1
{
    public static void main(String args[])
    {
// ...
        try
        {
// ...
            System.out.println("Getting an output stream...");
            OutputStream os = con.getOutputStream();
            System.out.println("Getting an input stream...");
            InputStream is = con.getInputStream();
// ...
        } catch (Throwable t)
          {
            t.printStackTrace();
          }
    }
}


A run of Listing 5.2 produces:

E:\classes\com\javaworld\jpitfalls\article3>java -Djava.compiler=NONE 
com.javaworld.jpitfalls.article3.BadURLPost1 
http://localhost/cgi-bin/echocgi.exe
Received a : sun.net.www.protocol.http.HttpURLConnection
Getting an output stream...
Getting an input stream...
After flushing output stream.
line: <HEAD>
line: <TITLE> Echo CGI program </TITLE>
line: </HEAD>
line: <BODY BGCOLOR='#ebebeb'><CENTER>
line: <H2> Echo </H2>
line: </CENTER>
line: No content! ERROR!
line: </BODY>
line: </HTML>


Although the program compiles and runs, the CGI program reports that no data was sent! Why? The side effects of getInputStream() bite us again, causing the POST request to be sent before anything is placed in the post's output buffer, thus sending an empty POST request.

After failing twice, we understand that getInputStream() is the key method that actually writes the requests to the server. Therefore we must perform the operations serially (open output, write, open input, read) as we do in Listing 5.3, GoodURLPost.

Listing 5.3 GoodURLPost.java

package com.javaworld.jpitfalls.article3;
import java.net.*;
import java.io.*;
public class GoodURLPost
{
    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.GoodURLPost 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", "" + msg.length()); 
// Not checked
            System.out.println("Msg Length: " + msg.length());
            System.out.println("Getting an output stream...");
            OutputStream os = con.getOutputStream();
            OutputStreamWriter osw = new OutputStreamWriter(os);
            osw.write(msg);
            osw.flush();
            osw.close();
            System.out.println("After flushing output stream. ");
            System.out.println("Getting an input stream...");
            InputStream is = con.getInputStream();
            // 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.3 produces:

E:\classes\com\javaworld\jpitfalls\article3>java -Djava.compiler=NONE 
com.javaworld.jpitfalls.article3.GoodURLPost 
http://localhost/cgi-bin/echocgi.exe
Received a : sun.net.www.protocol.http.HttpURLConnection
Msg Length: 35
Getting an output stream...
After flushing output stream.
Getting an input stream...
line: <HEAD>
line: <TITLE> Echo CGI program </TITLE>
line: </HEAD>
line: <BODY BGCOLOR='#ebebeb'><CENTER>
line: <H2> Echo </H2>
line: </CENTER>
line: Length of content: 35
line: Content: Hi HTTP SERVER! Just a quick hello!
line: </BODY>
line: </HTML>


Finally, success! We can now post data to a CGI program running on a Web server. To avoid the HTTP post pitfall, do not assume that the methods behave as they do for a Socket. Rather, the getInputStream() method has the side effect of writing the requests to the Web server. Therefore, you must observe the proper sequence.

  • Print
  • Feedback

Resources