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...)

On UploadForm page, I selected the same files:

File Upload Form:

Your email: [herong_yang@yahoo.com    ] 
Your comments: [I am uploading two files:     ]
               [   hello.txt                  ]
               [   dot.gif                    ]
File 1: [C:\hello.txt                  ] Browse...
File 2: [C:\dot.gif          ] Browse...
Submit

After clicking the submit button, I got the following result on the returning page:

-----------------------------7d59ec3031a
disposition: null: Content-Disposition: form-data; name="email"
blank: null: 
data: null: herong_yang@yahoo.com
boundary: null: -----------------------------7d59ec3031a
disposition: null: Content-Disposition: form-data; name="comment"
blank: null: 
data: null:  I am uploading two files:
data: null:    hello.txt
data: null:    dot.gif
boundary: null: -----------------------------7d59ec3031a
disposition: hello.txt: Content-Disposition: form-data; name="file...
type: hello.txt: Content-Type: text/plain
blank: hello.txt: 
boundary: null: -----------------------------7d59ec3031a
disposition: dot.gif: Content-Disposition: form-data; name="file2"...
type: dot.gif: Content-Type: image/gif
blank: dot.gif: 
boundary: null: -----------------------------7d59ec3031a
disposition: null: Content-Disposition: form-data; name="submit"
blank: null: 
data: null: Submit
boundary: null: -----------------------------7d59ec3031a--

To make sure that the uploaded files are saved correctly, I used the following commands in a command window:

comp \hello.txt \var\hello.txt
Comparing \hello.txt and \var\hello.txt...
Files compare OK

comp dot.gif \var\dot.gif
Comparing \dot.gif and \var\dot.gif...
Files compare OK

Beautiful, my program worked perfectly. Now let's a closer look at my program. It uses a number of logics to resolve some of the technical issues:

1. How to find out the encryption type? Since encryption type is not submitted in the HTTP request body, I have to use the following code to determine if the encryption type is multipart/form-data:

      if (enctype==null) {
         // try to determine the encryption type
         if (i>3 && sLine.startsWith("--")) {
            enctype = "form-data";
            boundary = sLine;
            ...

2. How to process a multiple parts data in a single loop? If multipart/form-data is used, the HTTP request body contains multiple parts, and each part contains a header section and a data section. How to read all the sections and all the parts in a single loop and process them accordingly? I used a status code to indicate the type of the current line in the reading loop. The following code shows you the logic used to determine the status of the current line based the status of the previous 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";
            }
         }

3. How and when to open and close the files to save the uploaded files? That's easy with the status code calculated correct. See the following the code:

         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;
            }
         }

4. How to save the uploaded data correctly? Saving the data is easy. But the last line of the data contains an extra new line character. I used a flag "holdNewLine" to hold the new line character if the current line has one:

         if (status.equals("data")) {
            if (file!=null) {
               if (holdNewLine) file.write(crlf);
               file.write(line,0,i);
               holdNewLine = hasNewLine;
               ......
            }

Conclusion

  • RFC 1867 defines a new HTML input type, FILE, for the browser to collect files to update.
  • RFC 1867 defines a new encryption type, multipart/form-data, for the browser to upload files in the HTTP request body in a multi-part format.
  • Uploaded files should be handled as binary data. The new line character of the last line in the uploaded files should be removed.
  • Be careful about saving uploaded files on a Web server. They should be saved in a secure area. Web server should avoid using the path name submitted by the browser. Web users could use it to damage your server file system.

Part:   1  2  3  4  5 

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