Web Category

The components of the web category are related in one way or other to
supplementing the web-related tasks for the Java programmer.

1. FileUpload

Summary: Ready-to-use file upload component.

Where:Main Page.
Since this component has not been officially released and the beta that was
released in February of this year is full of bugs, I advise you to download the
latest code from the nightly
builds.

Example Applications:fileuploaddemo.jsp, fileuploaddemo.htm, msg.jsp. Requires commons-fileupload-1.0-dev.jar in the WEB-INF/lib
directory of your application on the server.

Description:

FileUpload solves the common problem of handling file uploads
from the server point of view. It provides an easy-to-use interface to handle
files uploaded to the server and can be used in JSP pages and servlets. It
follows the RFC1867 standard,
parses input requests, and hands over to your application a list of individual items uploaded to
the server. Uploaded files are either kept in memory or in
a temporary location (configurable with a size parameter; if the uploaded file
size crosses the limit specified by the parameter, the files are written to a
temporary location). You can also set other parameters, such as the maximum
acceptable file sizes and the location of temporary files.

These are the steps needed to use FileUpload in your
application. I will illustrate this with the help of an example where two
different files on a single page need to be uploaded to the server.

Create the HTML page. Note that for forms that allow for file uploads,
the enctype must be specified and it must be equal to
multipart/form-data, and the request method must be
POST. Also note that our page not only contains provisions for two
files to be uploaded, but also a normal text field.

// first check if the upload request coming in is a multipart request
boolean isMultipart = FileUpload.isMultipartContent(request);

b. Create a handler for this request, and use it to parse the request.
Upon parsing, all of the form items are available in a list.

DiskFileUpload upload = new DiskFileUpload();
// parse this request by the handler
// this gives us a list of items from the request
List items = upload.parseRequest(request);

c. Iterate over this list to access individual file items. To distinguish
between items that are actual uploaded files versus regular form fields, use
the isFormField() method. Based on the required processing
scenarios, we could save the uploaded files, access them byte by byte, or open
an input stream on them.

Iterator itr = items.iterator();
while(itr.hasNext()) {
FileItem item = (FileItem) itr.next();
// check if the current item is a form field or an uploaded file
if(item.isFormField()) {
// get the name of the field
String fieldName = item.getFieldName();
// if it is name, we can set it in request to thank the user
if(fieldName.equals("name"))
request.setAttribute("msg", "Thank You: " + item.getString());
} else {
// the item must be an uploaded file save it to disk. Note that there
// seems to be a bug in item.getName() as it returns the full path on
// the client's machine for the uploaded file name, instead of the file
// name only. To overcome that, I have used a workaround using
// fullFile.getName().
File fullFile = new File(item.getName());
File savedFile = new File(getServletContext().getRealPath("/"),
fullFile.getName());
item.write(savedFile);
}
}

We could have restricted the size of uploaded files by using
upload.setSizeMax on the upload handler. This would cause an
exception to be thrown whenever a file is uploaded that is greater in size than
the one specified. In the example above, I have set this size to
-1, which allows all file sizes to be uploaded.

There are other, smaller variations to this scenario. As specified earlier,
you can open an input stream on the uploaded files, let them remain in memory
until a size threshold is reached, enquire about their content type, get their
contents as a String or a Byte array, and delete
them. All of this can be done by using simple methods on the FileItem
class (DefaultFileItem is an implementation of this class).

2. HttpClient

Summary: An API to extend the java.net package.
Provides functionality to mimic the usage of a browser.

When: When you are building web browser functionality; when your
application requires an efficient way of handling HTTP/HTTPS connections.

Example Application:HttpClientDemo.java. Requires
commons-httpclient.jar, common-logging.jar in the
CLASSPATH, and JDK version 1.4 and above.

Description:

HttpClient is an extensive library that extends and enhances
the basic java.net package. It is an extremely rich library that
can help you build various kinds of distributed applications that use the HTTP
protocol or embed it into your applications to leverage access over this
protocol. The library is perhaps much better documented than the other packages
in the Commons stable, and comes with several examples. I will delve into how
you can develop a simple application that can retrieve a web page. A similar
example exists in the tutorial
section of the documentation; I will extend this example to support SSL. Note
that JDK 1.4 and above is required for this example application because the
example application requires the Java Secure Socket Connection library, which is
part of the JDK from the 1.4 version.

Identify a page that you can download via HTTPS. I used
https://www.paypal.com/. Then make sure that the file
%JAVA_HOME%/jre/lib/security/java.security contains a line similar
to:

security.provider.2=com.sun.net.ssl.internal.ssl.Provider

After this, there is no difference in the way HTTPS connections are handled,
at least in terms of your application. If however, the root certificate used
on the remote site is not trusted by your Java implementation, you will need to
import it before you can continue.

Create an instance of HttpClient. Think of the
HttpClient class as the main application driver that is required
for all functions that you may want to perform. This class requires a Connection
Manager that manages the actual connections. The
HttpConnectionManager interface allows you to create your own
managers, or you can use the built-in SimpleHttpConnectionManager or
MultiThreadedHttpConnectionManager class. If you create a blank
instance of HttpClient, it defaults its connection manager to the
SimpleHttpConnectionManager.

Create a method instance. This defines which HTTP method you want to use
for transfer of information from the remote site. The possible values are GET,
POST, PUT, DELETE, HEAD, OPTIONS, and TRACE. These methods are implemented as
individual classes that implement the HttpMethod interface. For
our example, we will use GetMethod, creating it by passing the URL
that we want to GET.

// create a method instance.
HttpMethod method = new GetMethod(url);

Execute this method instance for this particular URL. This is where an
attempt is actually made to connect to the URL with the method that is
specified. Upon execution, the status code returned by the server is returned
by this method. Note that the executeMethod is on the client, and
not the method.

// execute the method.
statusCode = client.executeMethod(method);

Read the response from the server. If the previous attempt to connect
had been unsuccessful, the method would have thrown HttpException
or IOException. An IOException would indicate that
there is something wrong with the network and that retrying is unlikely to be
unsuccessful. The response can be read in as a byte array, as an input stream
or as a String. You can now process this input as you wish.

byte[] responseBody = method.getResponseBody();

Finally, release the connection so that it can be reused, if need be.

method.releaseConnection();

This has been a very simple discussion of the HttpClient library. There is
much more that can be done with it; it is robust and efficient and is likely be
officially released very soon.

The Net package is an extremely robust and professional suite of classes.
The classes in this library were initially part of a commercial product called
NetComponents.

The Net classes offer both low-level access to most of the protocols and a
high-level abstraction if you so desire. In most cases, the abstraction is
enough, as it does not involve you in parsing the low-level socket-level
commands for various protocols. Using the high-level abstraction does not take
away any of the functionality, though, and the API does a good job of providing
enough functionality without compromising on the available feature set.

The base class for all protocols is the SocketClient class. It
is an abstract class that groups the common functionality required for all
protocols. Using each of the different protocols is quite similar. First you use the connect
method to establish a connection to the remote server, do the service required
for the protocol, and finally disconnect from the server. Let us create an
example to illustrate this usage.

Create a relevant client. We will use a NNTPClient to
download the list of available newsgroups on a news server.

client = new NNTPClient();

Connect with this client to the news server. I have used a server with a
relatively short list of newsgroups. Please be kind to them.

client.connect("aurelia.deine.net");

Retrieve the list of newsgroups. The following command returns an array
of NewsGroupInfo objects. This array will be empty if there are no
newsgroups on this server, and null if an error occurs. Note that this command
will take a long time, as the whole list of newsgroups may be very big. Each
NewsGroupInfo object contains more information about the newsgroup
and has public commands that you can use to retrieve information such as article
count, last article posted, or posting permissions.

list = client.listNewsgroups();

Finally, disconnect from the server.

if (client.isConnected())
client.disconnect();

Similarly, you can use any of the rest of the clients, be it
FingerClient, POP3Client, TelnetClient,
or any other.

Conclusion

This concludes the discussion on the Web-related and Trivial categories. In the next
installment of this article, I will cover the XML and Packages categories. The
final installment will cover the Utilities package.

I hope you have fun trying the demos in this article and that I've given you
more insight into the often-chaotic world of Jakarta Commons. At the least, I
hope this article has piqued your interest in the Commons subproject and the
various useful APIs and libraries that it provides.