 entity body is the content of the HTTP request itself. It is best to illustrate this with an example. An example of an HTTP header is given below.
Accept: application/vnd.ms-excel, application/msword, */*
Accept-Language: en-au
Connection: Keep-Alive
Host: localhost
Referer:
User-Agent: Mozilla/4.0 (compatible; MSIE 4.01; Windows 98)
Content-Length: 32
Content-Type: application/x-www-form-urlencoded
Accept-Encoding: gzip, deflate
LastName=truman&FirstName=daniel
A lot is revealed in the HTTP header above. The first line tells us
that the browser that sends this request can accept a number of file
formats, including Microsoft Excel and Microsoft Word. It is followed
by the language used (in this case, Australian English), the type of
connection (keep-alive), and the name of the host (localhost). It also
tells the server that the request is sent from the
demo.jsp which is located in directory. Then in the
User-Agent entry, the Request tells that the user is using a Microsoft
Internet Explorer version 4.01, which is compatible with Netscape
4.0. The user operation system is also recorded to be Windows 98. The
meaning of the information to follow can be retrieved from the
previous tables.
Following the header is two pairs of carriage-return line-feed characters. The length of this separator is 4 bytes since each carriage-return line-feed character pair consists of the ASCII characters number 13 and 10. From the HTTP header above we can see that the body consists of the following code:
LastName=truman&FirstName=daniel
This is clearly from a form with two input boxes: one called
LastName with the value
truman and the other
named
FirstName with the value
daniel.
Note that the length of
LastName=truman&FirstName=daniel is 32.
Now that you have finished dissecting an HTTP request, you are ready to take this information to the coding stage. To program a complete file upload application, you need to know both the server side and the client side. First we will learn how to program the HTML on the client side, and then we will study the Java code for the server side.
Prior to the RFC 1867 standard, there were eight possible values
for the
type attribute of an
input element:
checkbox,
hidden,
image,
radio,
reset,
submit, and
text. While these form elements
have proven useful in a wide variety of applications in which input
from the user needs to be transferred to the server, none of these is
useful for sending a file, either text or binary. Next, it was
proposed that the Type attribute of an Input element has another
possible value:
file. In addition, it defines a new MIME
media type, multipart/form-data, and specifies the behavior of HTML
user agents when interpreting a form with
enctype="multipart/form-data" or
<input
type="file" /> tags.
The author of an HTML form who wants to request one or more files from a user might write:
<form action="Jsp1.jsp" enctype="multipart/form-data" method="post">
File to Upload: <input name="filename" type="file" />
<br />
<input type="submit" value="Upload" />
</form>
When.
Internet programming in Java always involves the use of Servlets or
JSP pages, depending on the architecture you choose to implement. This
means that you will use one of the classes or interfaces in the
javax.servlet package or the
javax.servlet.http package. The most important interface
is the Servlet interface in the
javax.servlet package
that must be implemented by all servlets. However, I will not present
an introduction to Servlets in this article and can only refer you to
Sun's Web site if you need more
details about this API. What is of importance here is the HTTP request
and how to process it. When working with the HTTP request, you will
work with either the
javax.servlet.ServletRequest
interface or
javax.servlet.http.HttpServletRequest. The
ServletRequest interface is a generic interface that is
extended by
HttpServletRequest to provide request
information for HTTP Servlets.
The
HttpServletRequest interface has the following
signature.
public interface HttpServletRequest extends ServletRequest
The Servlet container creates an
HttpServletRequest
object and passes it as an argument to the Servlet's service methods
(
doGet,
doPost, etc). For a File Upload
Bean, you can then pass this
HttpServletRequest object to
the Bean for further processing, like the one in this article.
Some important methods of
HttpServletRequest are given
in the following list.
public long getDateHeader(java.lang.String
name)
Returns the value of the specified request header as a.
public java.lang.String getHeader(java.lang.String
name)
Returns the value of the specified request header as a
String. If the request did not include a header of the specified name, this method returns
null. The header name is case insensitive. You can use this method with any request header.
public java.util.Enumeration
getHeaderNames()
Returns an enumeration of all the header names this request contains. If the request has no headers, this method returns an empty enumeration.
Some Servlet containers do not allow do not allow Servlets to access headers using this method, in which case this method returns
null
public java.util.Enumeration
getHeaders(java.lang.String name)
Returns all the values of the specified request header as an
Enumerationof
Stringobjects.
Some headers such as
Accept-Languagecan.
public java.lang.String getMethod()
Returns the name of the HTTP method with which this request was made, for example,
get,
post, or
put. This is the same as the value of the CGI variable
REQUEST_METHOD.
public java.lang.String
getPathInfo()
Returns any extra path information associated with the URL the client sent when it made this request. The extra path information follows the Servlet path but precedes the query string. This method returns
nullif there was no extra path information.
This is the same as the value of the CGI variable
PATH_INFO.
public java.lang.String
getPathTranslated()
Returns any extra path information after the Servlet name but before the query string and translates it to a real path. This is the same as the value of the CGI variable
PATH_TRANSLATED.
If the URL does not have any extra path information, this method returns
null.
public java.lang.String
getQueryString()
Returns the query string that is contained in the request URL after the path. This method returns null if the URL does not have a query string. This is the same as the value of the CGI variable
QUERY_STRING.
public java.lang.String
getRemoteUser()
Returns the login of the user making this request, if the user has been authenticated, or
nullif the user has not been authenticated. Whether the user name is sent with each subsequent request depends on the browser and type of authentication. This is the same as the value of the CGI variable
REMOTE_USER.
public java.lang.String
getRequestedSessionId()
null.
public java.lang.String
getRequestURI()
Returns the part of this request's URL from the protocol name up to the query string in the first line of the HTTP request.
public java.lang.String
getServletPath()
Returns the part of this request's URL that calls the Servlet. This includes either the Servlet name or a path to the Servlet, but does not include any extra path information or a query string. This is the same as the value of the CGI variable
SCRIPT_NAME.
public HttpSession getSession(boolean
create)
Returns the current
HttpSessionassociated with this request or, if there is no current session and
createis true, returns a new session.
If
createis false and the request has no valid
HttpSession, this method returns null.
To make sure the session is properly maintained, you must call this method before the response is committed.
public HttpSession getSession()
Returns the current session associated with this request or, if the request does not have a session, creates one.
To illustrate how you can process a file upload, you should
familiarize yourself with the HTTP request of an uploaded file. The
following small application demonstrates how to upload a file and
writes the HTTP request into a file. Viewing the file with a text
editor will reveal the format of the request, which in turn enables
you to extract the filename, the file content, and other useful
information that are mixed together. This small application is meant
as a preparation before we discuss the real File Upload Bean and
consists of an HTML file called
main.html, a JSP file
called
Jsp1.jsp, and a JavaBean called
SimpleBean.
The
main.html file is the one that the client can use
to select a file to upload to the server and is given as follows.
<html>
<head>
<title>File Upload</title>
</head>
<body>
<form action="jsp1.jsp" enctype="MULTIPART/FORM-DATA" method=post>
Author: <input type="text" name="author" />
<br />
Company: <input type="text" name="company" />
<br />
Select file to upload <input type="file" name="filename" />
<br />
<input type="submit" value="Upload" />
</form>
</body>
</html>
You can see that the
enctype attribute is used in the
<form> tag and its value is
"MULTIPART/FORM-DATA". There are four input elements
including the submit button. The first two are normal
text elements called Author and Company. The third one is
an element of type
file, the input element that is used
to select a file.
The
action attribute of the form has the value of
Jsp1.jsp, meaning that the request (and also the file
uploaded) is sent to the
Jsp1.jsp file.
The
Jsp1.jsp simply calls a Bean called
SimpleBean.
<jsp:useBean
<%
TheBean.doUpload(request);
%>
And here is the code for the SimpleBean Bean.
import java.io.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.ServletInputStream;
public class FileUploadBean {
public void doUpload(HttpServletRequest request) throws
IOException {
PrintWriter pw = new PrintWriter(
new BufferedWriter(new FileWriter("Demo.out")));
ServletInputStream in = request.getInputStream();
int i = in.read();
while (i != -1) {
pw.print((char) i);
i = in.read();
}
pw.close();
}
}
It will write everything on the
HttpServletRequest
object to a file named
Demo.out.
The user interface is given by the
main.html file and
is shown in Figure 1. For this example, we enter some input values for
the Author and Company input elements and select a file called
abisco.html with the following content. I select an HTML
file to upload because I would like to show the content of the file in
the format. Since an HTML file is more or less a text file, the
content will be easy to display.
The content of the
abisco.html file is as follows.
<html> <head> <title>Abisco</title> </head> </html>.
Also imported are Dictionary and Hashtable from the
java.util package and PrintWriter, BufferedWriter,
FileWriter, and IOException from the
java.io package..
The whole thing is illustrated by the following lines of code.
while (i != -1 && !newLine.startsWith(boundary)) {
i = in.readLine(line, 0, 128);
if ((i==boundaryLength+2 || i==boundaryLength+4) // + 4 is eof
&& (new String(line, 0, i).startsWith(boundary)))
pw.print(newLine.substring(0, newLine.length()-2));
else
pw.print(newLine);
newLine = new String(line, 0, i);
}
After the file content is saved to the disk, close the PrintWriter.
pw.close();
The non-file form elements can be retrieved similarly. Instead of writing the values to the disk, however, the name-value pairs are put into the Dictionary object.
fields.put(fieldName, fieldValue.toString());
private void setFilename(String s)
Once you compile the Bean, you can use it from your Servlet or JSP page. Chances are you are using the Bean with a Servlet/JSP container such as Tomcat. The easiest way to deploy the Bean is to compress the class file into a jar file and chuck it to the lib directory of Tomcat. You need to restart Tomcat for the jar file to be loaded.
The following are an HTML file and a JSP file that illustrate the use of the Bean. The HTML file contains a form with a few elements.
<html>
<head>
<title>File Upload</title>
</head>
<body>
<form action=jsp1.jsp enctype="MULTIPART/FORM-DATA" method=post>
Author: <input type=text name=author>
<br>
Company: <input type=text name=company>
<br>
Comment: <textarea name=comment></textarea>
<br>
Select file to upload <input type=file name=filename>
<br>
Description: <input type=text name=description>
<br>
<input type=submit
</form>
</body>
</html>
When the user submits the form, the HTTP request will be handed to
Jsp1.jsp, which uses the FileUpload Bean to process the
request. The code of the
Jsp1.jsp is given below.
<jsp:useBean
<%
TheBean.doUpload(request);
out.println("Filename:" + TheBean.getFilename());
out.println("<BR>Content Type:" + TheBean.getContentType());
out.println("<BR>Author:" + TheBean.getFieldValue("Author"));
out.println("<BR>Company:" + TheBean.getFieldValue("Company"));
out.println("<BR>Comment:" + TheBean.getFieldValue("Comment"));
%>
File upload is not an easy topic and code to process it is not readily available. This article has presented the theory as well as the code for a File Upload Bean. The compiled version of the Bean is available for download from my Web site.
Budi Kurniawan is a senior J2EE architect and author.
Return to ONJava.com.