Java tutorial
/* * Copyright (c) 2000-2004 Netspective Communications LLC. All rights reserved. * * Netspective Communications LLC ("Netspective") permits redistribution, modification and use of this file in source * and binary form ("The Software") under the Netspective Source License ("NSL" or "The License"). The following * conditions are provided as a summary of the NSL but the NSL remains the canonical license and must be accepted * before using The Software. Any use of The Software indicates agreement with the NSL. * * 1. Each copy or derived work of The Software must preserve the copyright notice and this notice unmodified. * * 2. Redistribution of The Software is allowed in object code form only (as Java .class files or a .jar file * containing the .class files) and only as part of an application that uses The Software as part of its primary * functionality. No distribution of the package is allowed as part of a software development kit, other library, * or development tool without written consent of Netspective. Any modified form of The Software is bound by these * same restrictions. * * 3. Redistributions of The Software in any form must include an unmodified copy of The License, normally in a plain * ASCII text file unless otherwise agreed to, in writing, by Netspective. * * 4. The names "Netspective", "Axiom", "Commons", "Junxion", and "Sparx" are trademarks of Netspective and may not be * used to endorse or appear in products derived from The Software without written consent of Netspective. * * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT A WARRANTY OF ANY KIND. ALL EXPRESS OR IMPLIED REPRESENTATIONS AND * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, * ARE HEREBY DISCLAIMED. * * NETSPECTIVE AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE OR ANY THIRD PARTY AS A * RESULT OF USING OR DISTRIBUTING THE SOFTWARE. IN NO EVENT WILL NETSPECTIVE OR ITS LICENSORS BE LIABLE FOR ANY LOST * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THE SOFTWARE, EVEN * IF IT HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. */ package com.netspective.sparx.fileupload; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.Enumeration; import java.util.HashMap; import java.util.Hashtable; import java.util.List; import java.util.Map; import java.util.StringTokenizer; import javax.servlet.ServletInputStream; import javax.servlet.http.HttpServletRequest; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * A simple file upload utility . The class uploads the file from a multipart * encoded form to a given directory. */ public class FileUpload { private Log log = LogFactory.getLog(FileUpload.class); // The multipart request private HttpServletRequest req; // Upload dir private String dir; // Name of the file being uploaded currently private String fileName; // Table of form fields v/s values private Hashtable map = new Hashtable(); // The boundary private String boundary = "--"; private byte[] buff = new byte[100 * 1024]; // Input stream from the request private ServletInputStream in; // Name of the form field private String paramName; // Content disposition name private String contentDisp; // tempFIle prefix private String prefix; // request variable for file private String uploadFileArg; /** * The constructor takes the request and upload dir path as paramters and * uploads all the files in the request to the dir. * * @param r - multipart encoded HttpServletRequest * @param uploadDir - The directory to which the files should be uploaded * * @throws IOException - If there was a problem reading the stream or * writing to the file. */ public FileUpload(HttpServletRequest r, String uploadDir, String prefix, String uploadFileArg) throws IOException { req = r; dir = uploadDir; this.prefix = prefix; this.uploadFileArg = uploadFileArg; upload(); } /** * The method reads the next line from the servlet input stream into a byte * array and returns a String form of the array.Returns null if it reaches the * end of the stream * * @return String The next line in the stream * * @throws IOException - If there was a problem reading the stream or */ private String readLine() throws IOException { int len = 0; String line = null; len = in.readLine(buff, 0, buff.length); if (len < 0) return null; line = new String(buff, 0, len, "ISO-8859-1"); return line; } /** * The method loops through the lines in the input stream and calls * writeToFile() if it encounters a file and readParam() if it encounters a * form field * * @throws IOException - If there was a problem reading the stream or */ public void upload() throws IOException { log.debug("upload() - processing request"); // Set the boundary string setBoundary(); // The request stream in = req.getInputStream(); int len = 0; // the first line is the boundary , ignore it String line = readLine(); while ((line = readLine()) != null) { log.debug("from request: " + line); // set dispostion, param name and filename setHeaders(line); // skip next line line = readLine(); // if there is a content-type specified, skip next line too, // and this is a file, so upload it to the file system if (line.toLowerCase().startsWith("content-type")) { line = readLine(); writeToFile(); continue; } else { // its a form field, read it. readParam(); } } } /** * Sets the boundary string for this request */ private void setBoundary() throws IOException { String temp = req.getContentType(); int index = temp.indexOf("boundary="); boundary += temp.substring(index + 9, temp.length()); } /** * Reads the form field and puts it in to a table */ private void readParam() throws IOException { String line = null; StringBuffer buf = new StringBuffer(); while (!(line = readLine()).startsWith(boundary)) { buf.append(line); } line = buf.substring(0, buf.length() - 2); if (map.containsKey(paramName)) { Object existingValue = map.get(paramName); List valueList = null; if (existingValue instanceof List) { valueList = (List) existingValue; } else { valueList = new ArrayList(); valueList.add(existingValue); } valueList.add(line); map.put(paramName, valueList); } map.put(paramName, line); } /** * Sets the content disposition, param name and file name fields * * @param line the content-disposition line */ public void setHeaders(String line) { StringTokenizer tokens = new StringTokenizer(line, ";", false); String token = tokens.nextToken(); String temp = token.toLowerCase(); int index = temp.indexOf("content-disposition="); contentDisp = token.substring(index + 21, token.length()); token = tokens.nextToken(); temp = token.toLowerCase(); index = token.indexOf("name="); paramName = token.substring(index + 6, token.lastIndexOf('"')); fileName = null; if (tokens.hasMoreTokens()) { token = tokens.nextToken(); temp = token.toLowerCase(); index = token.indexOf("filename="); fileName = token.substring(index + 10, token.length()); index = fileName.lastIndexOf('/'); if (index < 0) { index = fileName.lastIndexOf('\\'); } if (index < 0) { fileName = fileName.substring(0, fileName.lastIndexOf('"')); } else { fileName = fileName.substring(index + 1, fileName.lastIndexOf('"')); } } } /** * Reads the file content from the stream and writes it to the local file system * * @throws IOException - If there was a problem reading the stream */ private void writeToFile() throws IOException { // Open an o/p stream File tmpFile = File.createTempFile(prefix, "upload", new File(dir)); tmpFile.deleteOnExit(); log.debug("Setting: " + uploadFileArg + " to: " + tmpFile.getPath()); map.put(uploadFileArg, tmpFile.getPath()); //FileOutputStream out = new FileOutputStream (dir+File.separator+fileName); FileOutputStream out = new FileOutputStream(tmpFile); // this flag checks if \r\n needs to be written to the file // the servlet output stream appends these characters at the end of the // last line of the content, which should be skipped // so in the loop, all \r\n but for the last line are written to the file boolean writeCR = false; int len = 0; String line = null; map.put(paramName, fileName); // for each line while ((len = in.readLine(buff, 0, buff.length)) > -1) { line = new String(buff, 0, len); // if end of content, break if (line.startsWith(boundary)) break; if (writeCR) { writeCR = false; out.write('\r'); out.write('\n'); } if (len > 2 && buff[len - 2] == '\r' && buff[len - 1] == '\n') { writeCR = true; out.write(buff, 0, len - 2); } else { out.write(buff, 0, len); } } out.close(); } /** * Returns the value of a request parameter as a String, or null if * the parameter does not exist.The method overrides parent method. * * @param name The name of the parameter * * @return String The value of the paramter */ public String getParameter(String name) { log.debug("calling getParameter for :" + name); Object val = map.get(name); if (val == null) return null; log.debug("val is a: " + val.getClass().getName()); if (val instanceof String) { return (String) val; } else { List vals = (List) val; return (String) vals.get(0); } } /** * Returns an Enumeration of String objects containing the names of the * parameters contained in this request. If the request has no parameters, * the method returns an empty Enumeration.The method overrides parent method. * * @return Enumeration of String objects, each String containing the * name of a request parameter; or an empty Enumeration if the request has * no parameters */ public java.util.Enumeration getParameterNames() { return map.keys(); } /** * Returns an array of String objects containing all of the values the given * request parameter has, or null if the parameter does not exist. * The method overrides parent method. * * @param name the name of the parameter whose value is requested * * @return <String[] an array of String objects containing the * parameter's values */ public String[] getParameterValues(String name) { Object val = map.get(name); if (val == null) return null; if (val instanceof String) { return new String[] { (String) val }; } else { List vals = (List) val; return (String[]) vals.toArray(new String[vals.size()]); } } /** * Returns a Map of String names as keys, String arrays as values * containing all of the request. * * @return Map of String names as keys, String arrays as values */ public Map getParameterMap() { Map ret = new Hashtable(); for (Enumeration e = getParameterNames(); e.hasMoreElements();) { String name = (String) e.nextElement(); String[] values = getParameterValues(name); ret.put(name, values); } return ret; } }