| 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 = new DataInputStream(yahooConnection.getInputStream());
> > >                 String inputLine;

> > >                 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. You can use either way to read from a URL. However, sometimes reading from a URLConnection instead of reading directly from a URL might be more useful to you as you can use the URLConnection object for other tasks (like writing to the URL) at the same time.

> > 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.

> #### Writing to a URLConnection

> > Many HTML pages contain forms--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, and 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 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 a 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.
> > Hassan Schroeder, a member of the Java team, wrote a small cgi-bin script, named `backwards`, and made it available at our Web site, `java.sun.com`. You can use this script to test the following example program. If for some reason you can't get to our Web site; you can put the script somewhere on your network, name it `backwards`, and test the program locally.

> > 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 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.

> > Here's an example 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://java.sun.com/cgi-bin/backwards");
> > >                 URLConnection connection = url.openConnection();

> > >                 PrintStream outStream = new PrintStream(connection.getOutputStream());
> > >                 outStream.println("string=" + stringToReverse);
> > >                 outStream.close();

> > >                 DataInputStream inStream = new DataInputStream(connection.getInputStream());
> > >                 String inputLine;

> > >                 while ((inputLine = inStream.readLine()) != null) {
> > >                     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 non-alphanumeric 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.

> > Next the program creates the URL object--the URL for the `backwards` script on java.sun.com.

> > >     URL url = new URL("http://java.sun.com/cgi-bin/backwards");

> > Next, the program creates a URLConnection and then opens an output stream on that connection. The output stream is filtered through a PrintStream.

> > >     URLConnection connection = url.openConnection();
> > >     PrintStream outStream = new PrintStream(connection.getOutputStream());

> > The second line above calls the `getOutputStream()` method on the connection. If the URL does not support output, this method throws an UnknownServiceException. If the URL supports output, then this method returns an output stream that is connected to the standard input stream of the URL on the server side--the client's output is the server's input.

> > 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:

> > >     DataInputStream inStream = new DataInputStream(connection.getInputStream());
> > >     String inputLine;

> > >     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

| Working with URLs