Previous | Next | Trail Map | Custom Networking and Security | Working with URLs


Reading from and Writing to a URLConnection

If you've successfully used openConnection() to initiate communications with a URL, then you have a reference to a URLConnection object. The URLConnection class contains many methods that let you communicate with the URL over the network. URLConnection is an HTTP-centric class--many of its methods are useful only when working with HTTP URLs. However, most URL protocols let you read from and write to the connection so this page shows you how to both read from and write to a URL through a URLConnection object.

Reading from a URLConnection

The following program performs the same function as the program shown in Reading Directly from a URL. However, rather than opening a stream directly from the URL, this program explicitly opens a connection to the URL, gets an input stream on the connection, and reads from the input stream:
import java.net.*;
import java.io.*;

class ConnectionTest {
    public static void main(String args[]) {
        try {
            URL yahoo = new URL("http://www.yahoo.com/");
            URLConnection yahooConnection = yahoo.openConnection();
            DataInputStream dis;
            String inputLine;

            dis = new DataInputStream(yahooConnection.getInputStream());
            while ((inputLine = dis.readLine()) != null) {
                System.out.println(inputLine);
            }
            dis.close();
        } catch (MalformedURLException me) {
            System.out.println("MalformedURLException: " + me);
        } catch (IOException ioe) {
            System.out.println("IOException: " + ioe);
        }
    }
}
The output from this program should be identical to the output from the program that opens a stream directly from the URL.

Again if, instead of output from the program, you see the following error message:

IOException: java.net.UnknownHostException: www.yahoo.com
you may have to set the proxy host so that the program can find the www.yahoo.com server. You can set the proxy host through the command line when you run the program, like this:
java -DproxySet=true -DproxyHost=proxyhost ConnectionTest

Writing to a URLConnection

Many HTML pages contain forms, that is, text fields and other GUI objects that let you enter data to the server. After you type in the required information and initiate the query by clicking on a button, the Web browser you're using writes the data to the URL over the network. At the other end, a (usually) cgi-bin script on the server the data, processes it, then sends you back a response, usually in the shape of a new HTML page. This scenario is often used to support searching.

Many cgi-bin scripts use the POST METHOD for reading the data from the client. Thus writing to a URL is often known as posting to a URL. Server-side scripts that use the POST METHOD read from their standard input.


Note: Some server-side cgi-bin scripts use the GET METHOD to read your data. The POST METHOD is quickly making the GET METHOD obsolete because it's more versatile and its has no limitations on the amount of data that can be sent through the connection.

Your Java programs can also interact with cgi-bin scripts on the server-side. They simply must be able to write to ta URL thus providing data to the server. Your program can do this by following these steps:

  1. create a URL
  2. open a connection to the URL
  3. get an output stream from the connection. This output stream is connected to the standard input stream of the cgi-bin script on the server.
  4. write to the output stream
  5. close the output stream
Below is a sample program that writes to a URL.

We've put a small cgi-bin script, named backwards, at our Web site, www.javasoft.com, that you can use to test the following small application. The script at our Web site reads a string from its standard input, reverses the string, and writes the result to its standard output. The script is provided below in case you can't get to our Web site for some reason; you can put the script somewhere on your network, name it backwards, and test the program locally.

#!/opt/internet/bin/perl
read(STDIN, , {'CONTENT_LENGTH'});
@pairs = split(/&/, );
foreach  (@pairs)
{
    (, ) = split(/=/, );
     =~ tr/+/ /;
     =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex())/eg;
    # Stop people from using subshells to execute commands
     =~ s/~!/ ~!/g; 
    {} = ;
}

print "Content-type: text/plain\n\n";
print "{'string'} reversed is: ";
=reverse({'string'});
print "\n";
exit 0;
The script requires input of the following form: string=string_to_reverse, where string_to_reverse is the string whose characters you want displayed in reverse order.

Now here's a program that runs the backwards script over the network through a URLConnection:

import java.io.*;
import java.net.*;

public class ReverseTest {
    public static void main(String args[]) {
        try {
            if (args.length != 1) {
                System.err.println("Usage:  java ReverseTest string_to_reverse");
                System.exit(1);
            }
            String stringToReverse = URLEncoder.encode(args[0]);

            URL url = new URL("http://www.javasoft.com/cgi-bin/backwards");
            URLConnection connection = url.openConnection();
            PrintStream outStream = new PrintStream(connection.getOutputStream());

            DataInputStream inStream;
            String inputLine;

            outStream.println("string=" + stringToReverse);
            outStream.close();

            inStream = new DataInputStream(connection.getInputStream());
            while (null != (inputLine = inStream.readLine())) {
                System.out.println(inputLine);
            }
            inStream.close();
        } catch (MalformedURLException me) {
            System.err.println("MalformedURLException: " + me);
        } catch (IOException ioe) {
            System.err.println("IOException: " + ioe);
        }
    }
}
Let's examine the program and see how it works. First, the program processes its command line arguments:
if (args.length != 1) {
    System.err.println("Usage:  java ReverseTest string_to_reverse");
    System.exit(1);
}
String stringToReverse = URLEncoder.encode(args[0]);
These lines ensure that the user provides one and only one command line argument to the program and "encodes" it. The command line argument is the string to be reversed by the cgi-bin script backwards. The command line argument may have spaces or other "weird" characters in it. Those characters must be "encoded" because various processing may happen on the string on its way to the server. This is achieved by the URLEncoder class. There's more about the URLEncoder class and what the encode() method does in The URLEncoder Helper Class.

Next the program creates the URL object--the URL for the backwards script on www.javasoft.com.

URL url = new URL("http://www.javasoft.com/cgi-bin/backwards");
Next, the program creates a URLConnection and then opens an output stream on that connection. The output stream is filtered throught a PrintStream.
URLConnection connection = url.openConnection();
PrintStream outStream = new PrintStream(connection.getOutputStream());
The second line calls the getOutputStream() method on the connection. If the URL does not support output, this method will throw a UnknownServiceException. If the URL supports output, then this method returns an output stream which is connected to the standard input stream of the URL on the server side--the client's output is the server's input.

[PENDING: picture]

Next, the program writes the required information to the output stream and closes the stream:

outStream.println("string=" + stringToReverse);
outStream.close();
This line writes to the output stream using the println() method. So you can see, writing data to a URL is as easy as writing data to a stream. The data written to the output stream on the client-side is the input for the backwards script on the server-side. The ReverseTest program constructs the input in the form required by the script by concatenating string= to the encoded string to be reversed.

Often, as with this example, when you are writing to a URL you are passing information to a cgi-bin script which reads the information you write, performs some action and then sends information back to you via the same URL. So it's likely that you will want to read from the URL after you've written to it. The ReverseTest program does that next:

inStream = new DataInputStream(connection.getInputStream());
while (null != (inputLine = inStream.readLine())) {
    System.out.println(inputLine);
}
inStream.close();
When you run the ReverseTest program using Reverse Me as an argument, you should see this output:
Reverse Me
 reversed is: 
eM esreveR
Like previous examples in this section, you may set the proxy host when you run the program so that it can find the www.javasoft.com server. You can set the proxy host through the command line when you run the program. In addition to setting the proxy host you must also provide a string on the command line for the program to reverse:
java -DproxySet=true -DproxyHost=proxyhost ReverseTest "Reverse Me"


Previous | Next | Trail Map | Custom Networking and Security | Working with URLs