Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

pspdash
Class MultipartRequest  view MultipartRequest download MultipartRequest.java

java.lang.Object
  extended bypspdash.MultipartRequest

public class MultipartRequest
extends java.lang.Object

A Multipart form data parser. Parses an input stream and writes out any files found, making available a hashtable of other url parameters. As of version 1.17 the files can be saved to memory, and optionally written to a database, etc.

Copyright (C)2001 Jason Pell.

        This library is free software; you can redistribute it and/or
        modify it under the terms of the GNU Lesser General Public
        License as published by the Free Software Foundation; either
        version 2.1 of the License, or (at your option) any later version.
        
This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Email: jasonpell@hotmail.com Url: http://www.geocities.com/jasonpell

Version:
1.19 Moved the MultipartRequest into a package, and thus into a java archive for easier dissemination. Fixed a bug, where in netscape if a file was uploaded with an unrecognised extension, no Content-Type was specified, so the first line of the file was chopped off. Also modified the structure of the parse method to make it easier to manage. I was checking strFileName length and nullness in two if blocks, so I moved them together. This should make the parse(...) method easier to understand as well. 26/07/2001, 1.18 Fixed some serious bugs. A new method readAndWrite(InputStream in, OutputStream out) which now does the generic processing in common for readAndWriteFile and readFile. The differences are that now the two extra bytes at the end of a file upload are processed once, instead of after each line. Also if an empty file is encountered, an outputstream is opened, but then deleted if no data written to it. The getCharArray() method has been removed. Replaced by the new String(bytes, encoding) method using ISO8859_1 encoding to ensure that extended characters are supported. All creation of strings is done using this encoding. The addition of static methods setEncoding(String) and getEncoding() to allow the use of MultipartRequest with a specific encoding type. All instances of MultipartRequest will utilise the static charEncoding variable value, that the setEncoding() method can be used to set. Hopefully this will not introduce any latent problems. Started to introduce support for multiple file uploads with the same form field name, but not completed for v1.18. 26/06/2001, 1.17 A few _very_ minor fixes. Plus a cool new feature added. The ability to save files into memory. Thanks to Mark Latham for the idea and some of the code. 11/04/2001, 1.16 Added support for multiple parameter values. Also fixed getCharArray(...) method to support parameters with non-english ascii values (ascii above 127). Thanks to Stefan Schmidt & Michael Elvers for this. (No fix yet for reported problems with Tomcat 3.2 or a single extra byte appended to uploads of certain files). By 1.17 hopefully will have a resolution for the second problem. 14/03/2001, 1.15 A new parameter added, intMaxReadBytes, to allow arbitrary length files. Released under the LGPL (Lesser General Public License). 03/02/2001, 1.14 Fix for IE problem with filename being empty. This is because IE includes a default Content-Type even when no file is uploaded. 16/02/2001, 1.13 If an upload directory is not specified, then all file contents are sent into oblivion, but the rest of the parsing works as normal., 1.12 Fix, was allowing zero length files. Will not even create the output file until there is something to write. getFile(String) now returns null, if a zero length file was specified. 06/11/2000, 1.11 Fix, in case Content-type is not specified., 1.1 Removed dependence on Servlets. Now passes in a generic InputStream instead. "Borrowed" readLine from Tomcat 3.1 ServletInputStream class, so we can remove some of the dependencies on ServletInputStream. Fixed bug where a empty INPUT TYPE="FILE" value, would cause an exception., 1.0 Initial Release.

Field Summary
private  byte[] blockOfBytes
          Store a read from the input stream here.
private static java.lang.String charEncoding
          Define Character Encoding method here.
static int CONTENT_TYPE
           
static int CONTENTS
           
private  java.io.PrintWriter debug
           
static int FILENAME
          Define the array indexes for the htFiles Object array.
private  java.io.File fileOutPutDirectory
           
private  java.util.Hashtable htFiles
           
private  java.util.Hashtable htParameters
           
private  long intContentLength
           
private  long intTotalRead
           
private  boolean loadIntoMemory
           
static int MAX_READ_BYTES
          Prevent a denial of service by defining this, will never read more data.
static int READ_LINE_BLOCK
          Defines the number of bytes to read per readLine call.
static int SIZE
           
private  java.lang.String strBoundary
           
 
Constructor Summary
MultipartRequest(java.io.PrintWriter debug, java.lang.String strContentTypeText, int intContentLength, java.io.InputStream in, int intMaxReadBytes)
          Constructor - load into memory constructor
MultipartRequest(java.io.PrintWriter debug, java.lang.String strContentTypeText, int intContentLength, java.io.InputStream in, java.lang.String strSaveDirectory)
          Deprecated. Replaced by MultipartRequest(PrintWriter, String, int, InputStream, int) You can specify MultipartRequest.MAX_READ_BYTES for the intMaxReadBytes parameter
MultipartRequest(java.io.PrintWriter debug, java.lang.String strContentTypeText, int intContentLength, java.io.InputStream in, java.lang.String strSaveDirectory, int intMaxReadBytes)
          Constructor.
MultipartRequest(java.lang.String strContentTypeText, int intContentLength, java.io.InputStream in, java.lang.String strSaveDirectory)
          Constructor.
MultipartRequest(java.lang.String strContentTypeText, int intContentLength, java.io.InputStream in, java.lang.String strSaveDirectory, int intMaxReadBytes)
          Constructor.
 
Method Summary
private  void addFileParameter(java.lang.String strName, java.lang.Object[] fileObj)
          So we can put the logic for supporting multiple files with the same form field name in the one location.
private  void addParameter(java.lang.String strName, java.lang.String value)
          So we can put the logic for supporting multiple parameters with the same form field name in the one location.
protected  void debug(java.lang.String x)
          Use when debugging this object.
private static java.lang.String getBasename(java.lang.String strFilename)
          This needs to support the possibility of a / or a \ separator.
 java.lang.String getContentType(java.lang.String strName)
          Returns the Content-Type of a file.
static java.lang.String getEncoding()
          Returns the current encoding method.
 java.io.File getFile(java.lang.String strName)
          Returns a File reference to the uploaded file.
 java.io.InputStream getFileContents(java.lang.String strName)
          If files were uploaded into memory, this method will retrieve the contents of the file as a InputStream.
 java.lang.Object getFileParameter(java.lang.String strName, int type)
          Access an attribute of a file upload parameter record.
 java.util.Enumeration getFileParameterNames()
          This enumeration will return all INPUT TYPE=FILE parameter NAMES as encountered during the upload.
 long getFileSize(java.lang.String strName)
          Returns the File Size of a uploaded file.
 java.lang.String getFileSystemName(java.lang.String strName)
          Get the file system basename of an uploaded file.
 java.lang.String getHtmlTable()
          For debugging.
private static int getLengthMinusEnding(byte[] byteLine, int endOfArray)
          Returns the length of the line minus line ending.
private static int getLengthMinusEnding(java.lang.StringBuffer buf)
           
 java.util.Enumeration getParameterNames()
          An enumeration of all URL Parameters for the current HTTP Request.
 java.lang.String getURLParameter(java.lang.String strName)
          Return the value of the strName URLParameter.
 java.util.Enumeration getURLParameters(java.lang.String strName)
          Return an enumeration of all values for the strName parameter.
private static java.lang.String getValue(java.lang.String strName, java.lang.String strToDecode)
          Format of string name=value; name=value; If not found, will return null.
private  void init(java.io.PrintWriter debug, java.lang.String strContentTypeText, int intContentLength, java.io.InputStream in, int intMaxReadBytes)
          Initialise the parser.
private  void parse(java.io.InputStream in)
          This is the main parse method.
private  long readAndWrite(java.io.InputStream in, java.io.OutputStream out)
          Read from in, write to out, minus last two line ending bytes.
private  long readAndWriteFile(java.io.InputStream in, java.lang.String strFilename)
          Read a Multipart section that is a file type.
private  byte[] readFile(java.io.InputStream in)
          If the fileOutPutDirectory wasn't specified, just read the file to memory.
private  int readLine(java.io.InputStream in, byte[] bytesToBeRead)
          Reads at most READ_BLOCK blocks of data, or a single line whichever is smaller.
private  int readLine(java.io.InputStream in, byte[] b, int off, int len)
          Tomcat's ServletInputStream.readLine(byte[],int,int) Slightly Modified to utilise in.read()
Reads the input stream, one line at a time.
private  java.lang.String readParameter(java.io.InputStream in)
          Read parameters, assume already passed Content-Disposition and blank line.
static void setEncoding(java.lang.String enc)
          This method should be called on the MultipartRequest itself, not on any instances of MultipartRequest, because this sets up the encoding for all instances of multipartrequest.
private static java.lang.String trimQuotes(java.lang.String strItem)
          trimQuotes trims any quotes from the start and end of a string and returns the trimmed string...
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

charEncoding

private static java.lang.String charEncoding
Define Character Encoding method here.


debug

private java.io.PrintWriter debug

htParameters

private java.util.Hashtable htParameters

htFiles

private java.util.Hashtable htFiles

strBoundary

private java.lang.String strBoundary

fileOutPutDirectory

private java.io.File fileOutPutDirectory

loadIntoMemory

private boolean loadIntoMemory

intContentLength

private long intContentLength

intTotalRead

private long intTotalRead

MAX_READ_BYTES

public static final int MAX_READ_BYTES
Prevent a denial of service by defining this, will never read more data. If Content-Length is specified to be more than this, will throw an exception. This limits the maximum number of bytes to the value of an int, which is 2 Gigabytes.

See Also:
Constant Field Values

READ_LINE_BLOCK

public static final int READ_LINE_BLOCK
Defines the number of bytes to read per readLine call. 128K

See Also:
Constant Field Values

blockOfBytes

private byte[] blockOfBytes
Store a read from the input stream here. Global so we do not keep creating new arrays each read.


FILENAME

public static final int FILENAME
Define the array indexes for the htFiles Object array.

See Also:
Constant Field Values

CONTENT_TYPE

public static final int CONTENT_TYPE
See Also:
Constant Field Values

SIZE

public static final int SIZE
See Also:
Constant Field Values

CONTENTS

public static final int CONTENTS
See Also:
Constant Field Values
Constructor Detail

MultipartRequest

public MultipartRequest(java.lang.String strContentTypeText,
                        int intContentLength,
                        java.io.InputStream in,
                        java.lang.String strSaveDirectory)
                 throws java.lang.IllegalArgumentException,
                        java.io.IOException
Constructor.


MultipartRequest

public MultipartRequest(java.lang.String strContentTypeText,
                        int intContentLength,
                        java.io.InputStream in,
                        java.lang.String strSaveDirectory,
                        int intMaxReadBytes)
                 throws java.lang.IllegalArgumentException,
                        java.io.IOException
Constructor.


MultipartRequest

public MultipartRequest(java.io.PrintWriter debug,
                        java.lang.String strContentTypeText,
                        int intContentLength,
                        java.io.InputStream in,
                        java.lang.String strSaveDirectory)
                 throws java.lang.IllegalArgumentException,
                        java.io.IOException
Deprecated. Replaced by MultipartRequest(PrintWriter, String, int, InputStream, int) You can specify MultipartRequest.MAX_READ_BYTES for the intMaxReadBytes parameter

Constructor.


MultipartRequest

public MultipartRequest(java.io.PrintWriter debug,
                        java.lang.String strContentTypeText,
                        int intContentLength,
                        java.io.InputStream in,
                        int intMaxReadBytes)
                 throws java.lang.IllegalArgumentException,
                        java.io.IOException
Constructor - load into memory constructor


MultipartRequest

public MultipartRequest(java.io.PrintWriter debug,
                        java.lang.String strContentTypeText,
                        int intContentLength,
                        java.io.InputStream in,
                        java.lang.String strSaveDirectory,
                        int intMaxReadBytes)
                 throws java.lang.IllegalArgumentException,
                        java.io.IOException
Constructor.

Method Detail

setEncoding

public static void setEncoding(java.lang.String enc)
                        throws java.io.UnsupportedEncodingException
This method should be called on the MultipartRequest itself, not on any instances of MultipartRequest, because this sets up the encoding for all instances of multipartrequest. You can set the encoding to null, in which case the default encoding will be applied. The default encoding if this method is not called has been set to ISO-8859-1, which seems to offer the best hope of support for international characters, such as german "Umlaut" characters. Warning: In multithreaded environments it is the responsibility of the implementer to make sure that this method is not called while another instance is be constructed. When an instance of MultipartRequest is constructed, it parses the input data, and uses the result of getEncoding() to convert between bytes and strings. If setEncoding() is called by another thread, then subsequent string conversions in the private parse() method will utilise this new encoding, which will cause serious problems.


getEncoding

public static java.lang.String getEncoding()
Returns the current encoding method.


init

private void init(java.io.PrintWriter debug,
                  java.lang.String strContentTypeText,
                  int intContentLength,
                  java.io.InputStream in,
                  int intMaxReadBytes)
           throws java.lang.IllegalArgumentException,
                  java.io.IOException
Initialise the parser.


getURLParameter

public java.lang.String getURLParameter(java.lang.String strName)
Return the value of the strName URLParameter. If more than one value for a particular Parameter, will return the first. If an error occurs will return null.


getURLParameters

public java.util.Enumeration getURLParameters(java.lang.String strName)
Return an enumeration of all values for the strName parameter. Even if a single value for, will always return an enumeration, although it may actually be empty if not value was encountered for strName or it is an invalid parameter name.


getParameterNames

public java.util.Enumeration getParameterNames()
An enumeration of all URL Parameters for the current HTTP Request.


getFileParameterNames

public java.util.Enumeration getFileParameterNames()
This enumeration will return all INPUT TYPE=FILE parameter NAMES as encountered during the upload.


getContentType

public java.lang.String getContentType(java.lang.String strName)
Returns the Content-Type of a file.


getFileContents

public java.io.InputStream getFileContents(java.lang.String strName)
If files were uploaded into memory, this method will retrieve the contents of the file as a InputStream.


getFile

public java.io.File getFile(java.lang.String strName)
Returns a File reference to the uploaded file. This reference is to the files uploaded location, and allows you to read/move/delete the file. This method is only of use, if files were uploaded to the file system. Will return null if uploaded to memory, in which case you should use getFileContents(strName) instead.


getFileSystemName

public java.lang.String getFileSystemName(java.lang.String strName)
Get the file system basename of an uploaded file.


getFileSize

public long getFileSize(java.lang.String strName)
Returns the File Size of a uploaded file.


getFileParameter

public java.lang.Object getFileParameter(java.lang.String strName,
                                         int type)
Access an attribute of a file upload parameter record.


parse

private void parse(java.io.InputStream in)
            throws java.io.IOException
This is the main parse method.


addParameter

private void addParameter(java.lang.String strName,
                          java.lang.String value)
So we can put the logic for supporting multiple parameters with the same form field name in the one location.


addFileParameter

private void addFileParameter(java.lang.String strName,
                              java.lang.Object[] fileObj)
So we can put the logic for supporting multiple files with the same form field name in the one location. Assumes that this method will never be called with a null fileObj or strFilename.


readParameter

private java.lang.String readParameter(java.io.InputStream in)
                                throws java.io.IOException
Read parameters, assume already passed Content-Disposition and blank line.


readAndWrite

private long readAndWrite(java.io.InputStream in,
                          java.io.OutputStream out)
                   throws java.io.IOException
Read from in, write to out, minus last two line ending bytes.


readAndWriteFile

private long readAndWriteFile(java.io.InputStream in,
                              java.lang.String strFilename)
                       throws java.io.IOException
Read a Multipart section that is a file type. Assumes that the Content-Disposition/Content-Type and blank line have already been processed. So we read until we hit a boundary, then close file and return.


readFile

private byte[] readFile(java.io.InputStream in)
                 throws java.io.IOException
If the fileOutPutDirectory wasn't specified, just read the file to memory.


getLengthMinusEnding

private static final int getLengthMinusEnding(byte[] byteLine,
                                              int endOfArray)
Returns the length of the line minus line ending.


getLengthMinusEnding

private static final int getLengthMinusEnding(java.lang.StringBuffer buf)

readLine

private int readLine(java.io.InputStream in,
                     byte[] bytesToBeRead)
              throws java.io.IOException
Reads at most READ_BLOCK blocks of data, or a single line whichever is smaller. Returns -1, if nothing to read, or we have reached the specified content-length. Assumes that bytToBeRead.length indicates the block size to read.


getBasename

private static final java.lang.String getBasename(java.lang.String strFilename)
This needs to support the possibility of a / or a \ separator. Returns strFilename after removing all characters before the last occurence of / or \.


trimQuotes

private static final java.lang.String trimQuotes(java.lang.String strItem)
trimQuotes trims any quotes from the start and end of a string and returns the trimmed string...


getValue

private static final java.lang.String getValue(java.lang.String strName,
                                               java.lang.String strToDecode)
Format of string name=value; name=value; If not found, will return null.


readLine

private int readLine(java.io.InputStream in,
                     byte[] b,
                     int off,
                     int len)
              throws java.io.IOException
Tomcat's ServletInputStream.readLine(byte[],int,int) Slightly Modified to utilise in.read()
Reads the input stream, one line at a time. Starting at an offset, reads bytes into an array, until it reads a certain number of bytes or reaches a newline character, which it reads into the array as well.

This method does not returns -1 if it reaches the end of the input stream before reading the maximum number of bytes, it returns -1, if no bytes read.


debug

protected void debug(java.lang.String x)
Use when debugging this object.


getHtmlTable

public java.lang.String getHtmlTable()
For debugging.