ProblemYou want to upload more than one file at a time from a client, and handle each file as it is uploaded. SolutionUse the MultipartParser from Jason Hunter's cos.jar archive. DiscussionThe MultipartParser class allows the servlet to handle each file part sequentially as the server receives a multipart HTTP request.
In addition, the file's content type, size, and name can be read as the servlet handles the request. The servlet can also make basic checks using this class, such as counting how many files were uploaded and verifying whether the user uploaded a file for each of the available form input fields. The HTML file from Recipe 8.5 has been altered to allow the upload of three different files from the user's filesystem, as shown in Figure 8-2. Figure 8-2. An HTML form for uploading three filesThis HTML form is created by including three input tags with type="file ", as in: <input type="file" name="file1"><br><br> <input type="file" name="file2"><br><br> <input type="file" name="file3"> Example 8-4 handles the multiple file uploads by importing three classes from the cos.jar archive. The MultipartParser class restricts the size of file uploads to 5 MB in Example 8-4; however, you can set this constructor parameter to another value to allow smaller or larger file sizes, or leave the accepted file size at the 1 MB default.
The MultipartParser object throws a java.io.IOException if any of the file uploads exceed the size limit. Calling the MultipartParser.readNextPart( ) method returns a Part type, or null if the incoming stream does not contain any more parts . A Part can be either a FilePart or a ParamPart , depending on the content it includes. The ParamPart covers the other parameters that an HTML form might include, such as "username". The FilePart has several methods that provide information about the uploaded file, such as its content type and the filename. The FilePart.writeTo(java.io.File dir) method saves the file to the specified directory and returns the file size as a long type. The FilePart can also write to an OutputStream , as in writeTo(java.io.OutputStream out) . Example 8-4. A servlet handling multiple file uploadspackage com.jspservletcookbook; import javax.servlet.*; import javax.servlet.http.*; import com.oreilly.servlet.multipart.MultipartParser; import com.oreilly.servlet.multipart.Part; import com.oreilly.servlet.multipart.FilePart; public class ParserServlet extends HttpServlet { private String fileSavePath; public void init( ){ // save uploaded files to a 'data' directory in the web app fileSavePath = getServletContext( ).getRealPath("/") + "data"; } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, java.io.IOException { response.setContentType("text/html"); java.io.PrintWriter out = response.getWriter( ); out.println("<html>"); out.println("<head>"); out.println("<title>File uploads</title>"); out.println("</head>"); out.println("<body>"); out.println("<h2>Here is information about any uploaded files</h2>"); try{ // file limit size of 5 MB MultipartParser parser = new MultipartParser( request,5 * 1024 * 1024); Part _part = null; while ((_part = parser.readNextPart( )) != null) { if (_part.isFile( )) { // get some info about the file FilePart fPart = (FilePart) _part; String name = fPart.getFileName( ); if (name != null) { long fileSize = fPart.writeTo( new java.io.File(fileSavePath)); out.println("The user's file path for the file: " + fPart.getFilePath( ) + "<br>"); out.println("The content type of the file: " + fPart.getContentType( )+ "<br>"); out.println("The file size: " +fileSize+ " bytes<br><br>"); //commence with another file, if there is one } else { out.println( "The user did not upload a file for this part."); } } else if (_part.isParam( )) { // do something else if it is a non-file-type parameter, //such as a username } }// end while out.println("</body>"); out.println("</html>"); } catch (java.io.IOException ioe){ //an error-page in the deployment descriptor is //mapped to the java.io.IOException throw new java.io.IOException( "IOException occurred in: " + getClass( ).getName( )); } }//doPost public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, java.io.IOException { throw new ServletException( "GET method used with " + getClass( ).getName( )+ ": POST method required."); } } Figure 8-3 shows the descriptive page that the servlet displays about each uploaded file. Figure 8-3. A servlet displays information about uploaded filesSee AlsoRecipe 8.1 on preparing the HTML for a file upload; Recipe 8.4 on downloading and using the com.oreilly.servlet library; Recipe 8.5 on handling a single file upload in a servlet; Recipe 8.5 on controlling file naming; Recipe 8.6 on using a JSP to handle file uploads; the homepage for com.oreilly.servlet : http://www.servlets.com/cos/index.html; the RFC 1867 document on form-based file uploads: http://www.ietf.org/rfc/rfc1867.txt. |