URL connections are closely related
to URLs, as their name implies. Indeed, you get a reference to a
URLConnection
by using the
openConnection()
method of a
URL
object; in many ways, the
URL
class is only a wrapper around the
URLConnection
class. However, URL connections
provide more control over the communication between the client and
the server. In particular, URL connections provide not just input
streams by which the client can read data from the server, but also
output streams to send data from the client to the server. This is
essential for protocols like mailto.
The java.net.URLConnection
class is an abstract
class that handles communication with different kinds of servers,
like FTP servers and web servers. Protocol-specific subclasses of
URLConnection
, hidden inside the
sun
classes, handle different kinds of servers.
URL connections take place in five steps:
The URL
object is constructed.
The
openConnection()
method of the URL
object creates the
URLConnection
object.
The parameters for the connection and the request properties that the client sends to the server are set up.
The
connect()
method makes the connection to the server, perhaps using a socket for
a network connection or a file input stream for a local connection.
The response header information is read from the server.
Data is read from the connection by using the input stream returned
by getInputStream()
or through a content handler
with getContent()
. Data can be sent to the server
using the output stream provided by
getOutputStream()
.
This scheme is very much based on the HTTP/1.0 protocol. It does not fit other schemes that have a more interactive “request, response, request, response, request, response” pattern instead of HTTP/1.0’s “single request, single response, close connection” pattern. In particular, FTP and even HTTP/1.1 aren’t well suited to this pattern. I wouldn’t be surprised to see this replaced with something more general in a future version of Java.
URLConnection
objects are not constructed directly
in your own programs. Instead, you create a URL
for the particular resource, and call that
URL
’s openConnection()
method. This gives you a URLConnection
. Then the
getInputStream()
method returns an input stream
that reads data from the URL. (The openStream()
method of the URL
class is just a thin veneer over
the getInputStream()
method of the
URLConnection
class.) For example:
try { URL u = new URL("http://www.digitalthink.com/"); URLConnection uc = u.openConnection(); uc.connect(); InputStream in = uc.getInputStream(); //... } catch (IOException e) { //...
If the connection cannot be opened (possibly because the remote host
is unreachable), an IOException
is thrown. Example 5.2 reads a URL from the command line, opens a
connection to that URL, then prints the data returned by the server
at that URL. This is similar to Example 5.1;
WebCat
differs primarily in that it uses a
URLConnection
instead of a URL
.
Example 5-2. The WebCat Program
import java.net.*; import java.io.*; import com.macfaq.io.*; public class WebCat { public static void main(String[] args) { if (args.length == 0) { System.err.println("Usage: java WebCat url1 url2 ..."); return; } for (int i = 0; i < args.length; i++) { if (i > 0 && i < args.length) { System.out.println(); System.out.println("----------------------"); System.out.println(); } System.out.println(args[i] + ":"); try { URL u = new URL(args[i]); URLConnection uc = u.openConnection(); uc.connect(); InputStream in = uc.getInputStream(); StreamCopier.copy(in, System.out); in.close(); } catch (IOException e) {System.err.println(e);} } // end for } }
Writing data to a URLConnection
is similar to
reading data. However, you must first inform the
URLConnection
that you plan to use it for output,
and then, instead of getting the connection’s input stream and
reading from it, you get the connection’s output stream and
write to it. This is commonly used to talk to CGIs that use the POST
method or to store files on web servers through the PUT method, or to
communicate with a Java servlet running on a server. Here are the
steps for writing data on a URLConnection
:
Construct the URL
object.
Call the openConnection()
method of the
URL
object to create the
URLConnection
object.
Pass true
to setDoOutput(
) to
indicate that this URLConnection
will be used for
output.
If you also want to read input from the stream, invoke
setDoInput(true)
to indicate that this
URLConnection
will be used for input.
Create the data you want to send, preferably as a byte array.
Call getOutputStream()
to get an output stream
object. Write the byte array calculated in step 5 onto the stream.
Close the output stream.
Call getInputStream()
to get an input stream
object. Read and write it as usual.
Example 5.3 uses these steps to implement a simple
mail client. It forms a mailto URL from an email
address entered on the command line. Input for the message is copied
from System.in
onto the output stream of the
URLConnection
using a
StreamCopier
. The end of the message is indicated
by the end-of-stream character.
Example 5-3. The MailClient Class
import java.net.*; import java.io.*; import com.macfaq.io.*; public class MailClient { public static void main(String[] args) { if (args.length == 0) { System.err.println("Usage: java MailClient [email protected]"); return; } try { URL u = new URL("mailto:" + args[0]); URLConnection uc = u.openConnection(); uc.setDoOutput(true); uc.connect(); OutputStream out = uc.getOutputStream(); StreamCopier.copy(System.in, out); out.close(); } catch (IOException e) {System.err.println(e);} } }
For example, to send email to the author of this book:
% java MailClient [email protected]
hi there! ^D
MailClient
suffers from a few restrictions. The
proper way to detect the end of the message is to look for a period
on a line by itself. Proper or not, that style of user interface is
really antiquated, so I didn’t bother to implement it. To do so
properly, you’ll need to use a Reader
or a
Writer
; they’re discussed in Chapter 15. Furthermore, it only works in Java
environments that support the mailto protocol;
thus, it works under Sun’s JDK, but may not work in other
environments. It also requires that the local host be running an SMTP
server, or that the system property mailhost
must
contain the name of an accessible SMTP server, or that a machine in
the local domain named mailhost
be running an
SMTP server. Finally, the security manager must permit network
connections to that server, although this is not normally a problem
in an application.
18.222.196.175