To browse and select a file for upload you need a HTML <input type="file">
field in the form. As stated in the HTML specification you have to use the POST
method and the enctype attribute of the form have to be set to "multipart/form-data"
.
<form action="upload" method="post" enctype="multipart/form-data">
<input type="file" name="file" />
<input type="submit" />
</form>
After submitting such a form the binary multipart form data is available in the request body. The Servlet API prior to 3.0 doesn't support builtin facilities to access the multipart form data. The request.getParameter()
and consorts would all return null
. You can in theory parse it yourself based on HttpServletRequest#getInputStream()
. But this is a precise and tedious work which requires precise knowledge of RFC2388. The normal practice is to make use of Apache Commons FileUpload to parse the multpart form data requests. It has an excellent User Guide and FAQ (carefully go through both).
Here's a kickoff example how the doPost()
of your UploadServlet
may look like when using Commons FileUpload:
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
List<FileItem> items = new ServletFileUpload(new DiskFileItemFactory()).parseRequest(request);
for (FileItem item : items) {
if (item.isFormField()) {
// Process regular form field (input type="text|radio|checkbox|etc", select, etc).
String fieldname = item.getFieldName();
String fieldvalue = item.getString();
// ... (do your job here)
} else {
// Process form file field (input type="file").
String fieldname = item.getFieldName();
String filename = FilenameUtils.getName(item.getName());
InputStream filecontent = item.getInputStream();
// ... (do your job here)
}
}
} catch (FileUploadException e) {
throw new ServletException("Cannot parse multipart request.", e);
}
// ...
}
Alternatively you can also wrap this all in a Filter
which parses it all automagically and put the stuff back in the parametermap of the request so that you can continue using request.getParameter()
the usual way. You can find an example in this article.
If you're already on the fresh new Servlet 3.0 API, then you can just use standard API provided HttpServletRequest#getParts()
to collect the multipart form data items. This is a bit less convenienced than Commons FileUpload (utility methods needed), but still workable. The doPost()
of your UploadServlet
may then look like instead:
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
for (Part part : request.getParts()) {
String filename = getFilename(part);
if (filename == null) {
// Process regular form field (input type="text|radio|checkbox|etc", select, etc).
String fieldname = part.getName();
String fieldvalue = getValue(part);
// ... (do your job here)
} else if (!filename.isEmpty()) {
// Process form file field (input type="file").
String fieldname = part.getName();
filename = filename.substring(filename.lastIndexOf('/') + 1).substring(filename.lastIndexOf('\\') + 1); // MSIE fix.
InputStream filecontent = part.getInputStream();
// ... (do your job here)
}
}
// ...
}
private static String getFilename(Part part) {
for (String cd : part.getHeader("content-disposition").split(";")) {
if (cd.trim().startsWith("filename")) {
return cd.substring(cd.indexOf('=') + 1).trim().replace("\"", "");
}
}
return null;
}
private static String getValue(Part part) throws IOException {
String value = new BufferedReader(new InputStreamReader(part.getInputStream(), "UTF-8")).readLine();
return (value != null) ? value : ""; // Must be empty String according HTTP spec.
}
Also this can be done in a Filter
which does all the job transparently so that you can continue using the getParameter()
as usual. You can find an example in this article.
Hope this helps :)