JSP and JSTL Tutorials - Herong's Tutorial Notes
Dr. Herong Yang, Version 3.09, 2006

File Upload

Part:   1  2  3  4  5 

JSP/JSTL Tutorials - Herong's Tutorial Notes © Dr. Herong Yang

Using Cookies

Using JavaBean Classes

HTTP Response Header Lines

Non ASCII Characters

JSTL and Expression Language

File Upload

Execution Context

JSP Elements

JSP Standard Tag Libraries (JSTL)

JSP Custom Tag

... Table of Contents

(Continued from previous part...)

UploadSave.jsp - Saving Uploaded Files

As you can see from the previous section, dumping uploaded files back to the browser is easy. But saving uploaded files on the server machine correctly is not so easy. I wrote the following JSP program, UploadSave.jsp, that scans the HTTP request body and saves uploaded files if there are any:

<?xml version="1.0"?>
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" version="1.2">
<!--
 - UploadSave.jsp
 - Copyright (c) 2004 by Dr. Herong Yang. All rights reserved.
-->
<jsp:directive.page contentType="text/html"/>
<jsp:directive.page import="java.io.*"/>
<html><body>
<p>
<jsp:scriptlet><![CDATA[
   out.println("<pre>");
   ServletInputStream in = request.getInputStream();
   byte[] line = new byte[128];
   byte[] crlf = {(byte) 0x0D, (byte) 0x0A}; // \r\n
   String sLine = null;
   String enctype = null;
   String boundary = null;
   String status = null;
   String fName = null;
   FileOutputStream file = null;
   int i = in.readLine(line, 0, 128);
   boolean holdNewLine = false;
   while (i != -1) {
      boolean hasNewLine = i>=2 && line[i-1]==crlf[1] 
         && line[i-2]== crlf[0];
      if (hasNewLine) i = i-2;
      sLine = new String(line, 0, i);
      if (enctype==null) {
         // try to determine the encryption type
         if (i>3 && sLine.startsWith("--")) {
            enctype = "form-data";
            boundary = sLine;
            status = "boundary";
         } else {
            enctype = "x-www-form-urlencoded";
         }
         out.println(sLine);
      } else if (enctype.equals("x-www-form-urlencoded")) {
         out.println(sLine);
      } else if (enctype.equals("form-data")) {
         // Calculating the status of the current line
         if (status.equals("boundary")) {
            // Expecting the "Content-Disposition:" line
            status = "disposition";
         } else if (status.equals("disposition")) {
            // Expecting the "Content-Type:" line or a blank line
            if (sLine.startsWith("Content-Type:")) {
               status = "type";
            } else {
               status = "blank";
            }
         } else if (status.equals("type")) {
            // Expecting a blank line
            status = "blank";
         } else if (status.equals("blank")||status.equals("data")) {
            // Expecting the data or boundary
            if (sLine.startsWith(boundary)) {
               status = "boundary";
            } else {
               status = "data";
            }
         }
         // Now "status" is updated. Let's do the saving and echoing
         if (status.equals("disposition")) {
            // Getting the file name and open a file for saving
            int l = sLine.indexOf("filename=");
            if (l>=0) { 
               fName = sLine.substring(l+9);
               fName = fName.replaceAll("\"",""); 
               l = fName.lastIndexOf("\\");
               if (l>=0) fName = fName.substring(l+1);
               if (fName.length()>0) 
                  file = new FileOutputStream("\\var\\"+fName);
            } 
         } else if (status.equals("boundary")) {
            fName = null;
            if (file!=null) {
               file.close();
               file = null;
            }
         }
         if (status.equals("data")) {
            if (file!=null) {
               if (holdNewLine) file.write(crlf);
               file.write(line,0,i);
               holdNewLine = hasNewLine;
            } else {
               out.println(status+": "+fName+": "+sLine);
               holdNewLine = false;
            }
         } else {
            out.println(status+": "+fName+": "+sLine);
            holdNewLine = false;
         }
      }
      i = in.readLine(line, 0, 128);
   }
   out.println("</pre>");
]]></jsp:scriptlet>
</p>
</body></html>
</jsp:root>

I repeated my previous upload test with UploadSave.jsp by using the UploadInit.html page:

File Upload Test Settings:

File upload handler: [UploadSave.jsp]
Submit method: [post]
Encryption type: [multipart/form-data              ]
Submit

(Continued on next part...)

Part:   1  2  3  4  5 

Dr. Herong Yang, updated in 2006
JSP and JSTL Tutorials - Herong's Tutorial Notes - File Upload