● Getting Files Using Sockets
● Performing a Query with GET ● Posting Data with the URL Class ● Posting Data Using Sockets ● Supporting the Cookie Protocol
Java and Web Servers
The Web server is the home of a Java applet. Not only does the applet live there, it must rely on the Web server for any information or files it wants to download. As some of the applet security restrictions are lifted and replaced with a better security mechanism, this will not be the case. For now, however, the Web server is the only place an applet can count on being able to access. Applications, on the other hand, may access data in countless ways, but still find Web servers to be a wonderful source of information.
Getting Files Using the URL Class
The URL class allows you to access any URL on the World Wide Web, as long as your browser or Java environment supports the protocol for the URL. You can safely assume that your environment supports the HTTP protocol. Other protocols such as FTP may not be available, however. Keep in mind that if you open an URL and read it yourself, there is no way to take the data you read and display it as a fully-formatted HTML page unless you do it yourself. If you want to open an URL and have your browser display it, you should use the showDocument method in the Applet class, which is discussed in the section, "Loading Another URL from an Applet," in Chapter 7 "Creating Smarter Forms."
The URL class is really just a class for naming resources on the World Wide Web, much like the File class represents file names, but not the contents of a file. In order to get the contents of an URL, you need to open an input stream to the URL. You can do this one of two ways. The simplest way is to call the openStream method in the URL class:
URL someURL = new URL("http://abcdef.com/mydocument.html"); InputStream inStream = someURL.openStream();
Chapter 6 -- Communicating with a Web Server
This input stream will provide you with the contents of the file named by the URL. This method is most useful when you are only concerned with the file contents and not with any of the HTTP headers associated with the file. To get these, you need to use the URLConnection class.
The URLConnection class represents a network connection to a WWW resource. When you open an input stream on an
URL, it really opens an URLConnection and then calls the getInputStream in the URLConnection object. The following code fragment is the equivalent of the previous example:
URL someURL = new URL("http://abcdef.com/mydocument.html"); URLConnection urlConn = someURL.openConnection();
InputStream inStream = urlConn.getInputStream();
The advantage of the URLConnection class is that it gives you much finer control over an URL connection. For example, you can retrieve the headers associated with the file. The two header fields that you will probably be most interested in are the content type and content length. You can fetch these with the getHeaderField and
getHeaderFieldInt methods:
String contentType = urlConn.getHeaderField("content-type"); int contentLength = urlConn.getHeaderFieldInt(
"content-length", -1); // returns -1 if length isn't specified
These header fields are so popular, in fact, that they have their own special methods that do the equivalent of the above code-getContentType and getContentLength:
String contentType = urlConn.getContentType(); int contentLength = urlConn.getContentLength();
Listing 6.1 shows a sample applet that uses an URL class to read its own .class file.
Listing 6.1 Source Code for FetchURL.java
import java.applet.*; import java.awt.*; import java.net.*; import java.io.*;
// This applet demonstrates the use of the URL and URLConnection // class to read a file from a Web server. The applet reads its // own .class file, because you can always be sure it exists. public class FetchURL extends Applet
{
byte[] appletCode; // Where to store the contents of the .class file public void init()
{
try {
Chapter 6 -- Communicating with a Web Server
// Open a URL to this applet's .class file. You can locate it by // using the getCodeBase method and the applet's class name. URL url = new URL(getCodeBase(),
getClass().getName()+".class"); // Open a URLConnection to the URL
URLConnection urlConn = url.openConnection();
// See if you can find out the length of the file. This allows you to // create a buffer exactly as large as you need.
int length = urlConn.getContentLength();
// Because you can't be sure of the size of the .class file, use a
// ByteArrayOutputStream as a temporary container. Once you are finished // reading, you can convert it to a byte array.
ByteArrayOutputStream tempBuffer;
// If you don't know the length of the .class file, use the default size if (length < 0) {
tempBuffer = new ByteArrayOutputStream(); } else {
tempBuffer = new ByteArrayOutputStream(length); }
// Get an input stream to this URL
InputStream instream = urlConn.getInputStream(); // Read the contents of the URL and copy it to the temporary buffer int ch;
while ((ch = instream.read()) >= 0) { tempBuffer.write(ch);
}
// Convert the temp buffer to a byte array (you don't do anything with // the array in this applet other than take its size).
appletCode = tempBuffer.toByteArray(); } catch (Exception e) {
e.printStackTrace(); }
}
public void paint(Graphics g) {
g.setColor(Color.black); if (appletCode == null) {
g.drawString("I was unable to read my .class file", 10, 30);
} else {
g.drawString("This applet's .class file is "+ appletCode.length+" bytes long.", 10, 30);
Chapter 6 -- Communicating with a Web Server
} }
}
Figure 6.1 shows the output from the FetchURL applet.
Figure 6.1 : An applet can perform an HTTP GET using the URL class.
The FetchURL applet is a typical example of an applet that opens an URL and reads data from it. For example purposes, the applet reads its own .class file. There is no advantage to reading a .class file, but for example purposes it is quite handy, because you know for sure that the .class file must be there. If the .class file wasn't there, the applet wouldn't run in the first place.
The applet first opens the URL, and then gets an input stream for the URL. It tries to get the content length, which indicates how much data there is to retrieve. This value isn't always available, however, so the applet uses
ByteArrayOutputStream as a temporary storage mechanism.
Tip
Vectors and byte array output streams are extremely handy storage containers when you don't know the size of the data you are storing. You should use a vector whenever you need to store an unknown number of objects. The byte array output stream is a handy alternative to the vector when you are storing bytes.
Once the applet has read its .class file, it simply displays a message telling how many bytes it read.