Code 4 - Save File - UploadSave.jspx

This section provides a tutorial example of a JSP page, UploadSave.jspx, that reads the uploaded file and saves it on the Web server. The key logic is the request.getInputStream() call.

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="2.1">
<!-- UploadSave.jspx
 - Copyright (c) 2012, HerongYang.com, 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(
                     application.getRealPath("/upload/"+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>

Note that I am planning to save uploaded files in the .\upload directory under the Tomcat application document directory: \local\apache-tomcat-7.0.32\webapps\ROOT. So I have to create the .\upload directory first.

More notes are provided in later sections.

Last update: 2012.

Table of Contents

 About This Book

 JSP (JavaServer Pages) Overview

 Tomcat 7 Installation on Windows Systems

 JSP Scripting Elements

 Java Servlet Introduction

 JSP Implicit Objects

 Syntax of JSP Pages and JSP Documents

 JSP Application Session

 Managing Cookies in JSP Pages

 JavaBean Objects and "useBean" Action Elements

 Managing HTTP Response Header Lines

 Non-ASCII Characters Support in JSP Pages

 Performance of JSP Pages

 EL (Expression Language)

 Overview of JSTL (JSP Standard Tag Libraries)

 JSTL Core Library

 JSP Custom Tags

 JSP Java Tag Interface

 Custom Tag Attributes

 Multiple Tags Working Together

File Upload Test Application

 RFC 1867 - Form-based File Upload in HTML

 Code 1 - Display Options - UploadInit.html

 Code 2 - Display Form - UploadForm.jspx

 Code 3 - Dump File - UploadDump.jspx

 Test 1 - GET Method - Failed

 Test 2 - POST Method - Successful

Code 4 - Save File - UploadSave.jspx

 Test 3 - Save File - Successful

 Code Review - UploadSave.jspx

 Outdated Tutorials

 References

 PDF Printing Version