File upload is very common in web applications. It is very easy to implement file upload function in jsp environment, because there are many file upload components developed in Java on the Internet. This article takes the commons-fileupload component as an example to add file upload function to jsp applications.
The common-fileupload component is one of apache's open source projects and can be downloaded from http://jakarta.apache.org/commons/fileupload/.
This component allows you to upload one or more files at a time and can limit file size.
After downloading, unzip the zip package and copy commons-fileupload-1.0.jar to tomcat's webapps under your webappWEB-INFlib. If the directory does not exist, please create your own directory.
Create a new servlet: Upload.java for file upload:
import java.io.*; import java.util.*; import javax.servlet.*; import javax.servlet.http.*; import org.apache.commons.fileupload.*; public class Upload extends HttpServlet {private String uploadPath = "C:upload"; // directory for uploading files private String tempPath = "C:uploadtmp"; // temporary file directory public void doPost(HttpServletRequest request,HttpServletResponse response)throws IOException, ServletException{}}In the doPost() method, when the servlet receives the Post request issued by the browser, it realizes file upload. Here is the sample code:
public void doPost(HttpServletRequest request,HttpServletResponse response)throws IOException, ServletException{try {DiskFileUpload fu = new DiskFileUpload(); // Set the maximum file size, here is 4MBfu.setSizeMax(4194304); // Set the buffer size, here is 4kbfu.setSizeThreshold(4096); // Set the temporary directory: fu.setRepositoryPath(tempPath); // Get all files: List fileItems = fu.parseRequest(request); Iterator i = fileItems.iterator(); // Process each file in sequence: while(i.hasNext()) {FileItem fi = (FileItem)i.next(); // Get the file name, the file name includes the path: String fileName = fi.getName(); // Here you can record user and file information // ...// Write to the file, the tentative file name is a.txt, and the file name can be extracted from fileName: fi.write(new File(uploadPath + "a.txt")); }}catch(Exception e) {// You can jump to the error page}}If you want to read the specified upload folder in the configuration file, you can execute it in the init() method:
public void init() throws ServletException {uploadPath = ....tempPath = ....// If the folder does not exist, it will be automatically created: if(!new File(uploadPath).isDirectory())new File(uploadPath).mkdirs(); if(!new File(tempPath).isDirectory())new File(tempPath).mkdirs(); }Compile the servlet, be careful to specify the classpath, make sure to include commons-upload-1.0.jar and tomcatcommonlibservlet-api.jar.
Configure the servlet, use notepad to open tomcatwebapps for your webappWEB-INFweb.xml, and create a new one if not.
Typical configurations are as follows:
〈?xml version="1.0" encoding="ISO-8859-1"?〉〈!DOCTYPE web-appPUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN""http://java.sun.com/dtd/web-app_2_3.dtd">〈web-app>〈servlet>〈servlet-name>Upload〈/servlet-name>〈servlet-class>Upload〈/servlet-class>〈servlet-mapping〈servlet-name>Upload〈/servlet-name>〈url-pattern〉/fileupload〈/url-pattern〈/servlet-mapping〈/web-app〈
After configuring the servlet, start tomcat and write a simple html test:
〈form action="fileupload" method="post"enctype="multipart/form-data" name="form1">〈input type="file" name="file">〈input type="submit" name="Submit" value="upload">〈/form>
Note action="fileupload" where fileupload is the url-pattern specified when configuring the servlet.
Here is the code for a prawn:
This Upload is much easier to use than smartUpload. It was completely created by me bytes one by one, unlike smartUpload that has many bugs.
Calling method:
Upload up = new Upload(); up.init(request); /**Can call setSaveDir(String saveDir); Set the save path and call setMaxFileSize(long size) to set the maximum byte of uploaded file. Call setTagFileName(String) to set the name of the file after upload (only valid for the first file)*/up. uploadFile();
Then String[] names = up.getFileName(); get the uploaded file name, the absolute path of the file should be
Saved directory saveDir+"/"+names[i];
You can get the uploaded text or up.getParameterValues("filed") through up.getParameter("field");
Get the values of fields with the same name such as multiple checkBoxes.
Try the others yourself.
The source code is as follows: ______________________________________________________________________
package com.inmsg.beans; import java.io.*; import java.util.*; import javax.servlet.*; import javax.servlet.http.*; public class Upload {private String saveDir = "."; //Path to save the file private String contentType = ""; //Document type private String charset = ""; //Character set private ArrayList tmpFileName = new ArrayList(); //Temporary data structure for storing file names private Hashtable parameter = new Hashtable(); //Data structure that stores parameter names and values private ServletContext context; //Program context, used to initialize private HttpServletRequest request; //Instance used to pass in request object private String boundary = ""; //Memory data separator private int len = 0; //Byte length actually read from the inner every time private String queryString; private int count; //Total number of uploaded files private String[] fileName; //Uploaded file name array private long maxFileSize = 1024 * 1024 * 10; //Maximum file upload bytes; private String tagFileName = ""; public final void init(HttpServletRequest request) throws ServletException {this.request = request; boundary = request.getContentType().substring(30); //Get the in-memory data delimiter queryString = request.getQueryString(); }public String getParameter(String s) { //Used to get the parameter value of the specified field, override request.getParameter(String s) if (parameter.isEmpty()) { return null; }return (String) parameter.get(s); }public String[] getParameterValues(String s) { //Used to get the parameter array specified with the same name field, override request.getParameterValues(String s)ArrayList al = new ArrayList(); if (parameter.isEmpty()) {return null; }Enumeration e = parameter.keys(); while (e.hasMoreElements()) {String key = (String) e.nextElement(); if ( -1 != key.indexOf(s + "|||||||||||") || key.equals(s)) {al.add(parameter.get(key)); }}if (al.size() == 0) {return null; }String[] value = new String[al.size()]; for (int i = 0; i 〈 value.length; i++) {value[i] = (String) al.get(i); }return value; }public String getQueryString() {return queryString; }public int getCount() {return count; }public String[] getFileName() {return fileName; }public void setMaxFileSize(long size) {maxFileSize = size; }public void setTagFileName(String filename) {tagFileName = filename; }public void setSaveDir(String saveDir) { //Set the path to save for uploading the file this.saveDir = saveDir; File testdir = new File(saveDir); //To ensure that the directory exists, if there is no, create the directory if (!testdir.exists()) {testdir.mkdir(); }}public void setCharset(String charset) { //Set the character set this.charset = charset; }public boolean uploadFile() throws ServletException, IOException { //Upload method called by the user setCharset(request.getCharacterEncoding()); return uploadFile(request.getInputStream()); }private boolean uploadFile(ServletInputStream servletinputstream) throws //The main method to obtain central storage data ServletException, IOException {String line = null; byte[] buffer = new byte[256]; while ( (line = readLine(buffer, servletinputstream, charset)) != null) {if (line.startsWith("Content-Disposition: form-data; "))) {int i = line.indexOf("filename="); if (i 〉= 0) { //If there is filename= in the description in a delimiter, it means that it is the encoded content of the file String fName = getFileName(line); if (fName.equals("")) {continue; }if (count == 0 && tagFileName.length() != 0) {String ext = fName.substring( (fName.lastIndexOf(".") + 1)); fName = tagFileName + "." + ext; }tmpFileName.add(fName); count++; while ( (line = readLine(buffer, servletinputstream, charset)) != null) {if (line.length() 〈= 2) {break; }}File f = new File(saveDir, fName); FileOutputStream dos = new FileOutputStream(f); long size = 0l; while ( (line = readLine(buffer, servletinputstream, null)) != null) {if (line.indexOf(boundary) != -1) {break; }size += len; if (size 〉 maxFileSize) {throw new IOException("File exceeds" + maxFileSize + "byte!"); }dos.write(buffer, 0, len); }dos.close(); }else { //Otherwise it is the content of the field encoding String key = getKey(line); String value = ""; while ( (line = readLine(buffer, servletinputstream, charset)) != null) {if (line.length() 〈= 2) {break; }}while ( (line = readLine(buffer, servletinputstream, charset)) != null) {if (line.indexOf(boundary) != -1) {break; }value += line; }put(key, value.trim(), parameter); }}}if (queryString != null) {String[] each = split(queryString, "&"); for (int k = 0; k 〈 each.length; k++) {String[] nv = split(each[k], "="); if (nv.length == 2) {put(nv[0], nv[1], parameter); }}}fileName = new String[tmpFileName.size()]; for (int k = 0; k 〈 fileName.length; k++) {fileName[k] = (String) tmpFileName.get(k); //Pour the temporary file name in ArrayList into the data for user to call}if (fileName.length == 0) {return false; //If fileName data is empty, it means that no file is uploaded}return true; }private void put(String key, String value, Hashtable ht) {if (!ht.containsKey(key)) {ht.put(key, value); }else { //If you already have a KEY with the same name, you must rename the current key. At the same time, be careful not to form the same name as KEY try {Thread.currentThread().sleep(1); //In order not to generate two identical keys in the same ms}catch (Exception e) {}key += "||||||||||||" + System.currentTimeMillis(); ht.put(key, value); }}/* Call ServletInputstream.readLine(byte[] b,int offset,length) method, which reads a line from the ServletInputstream stream to the specified byte array. In order to ensure that it can accommodate a line, the byte[]b should not be less than 256. In the rewritten readLine, a member variable len is called to the actual number of bytes read (some lines are less than 256). When writing the file content, the byte of the len length should be written from the byte array instead of the entire length of byte[]. However, the rewritten method returns String to analyze the actual content and cannot return len, so len is set as a member variable and assign the actual length to it each time the read operation. That is to say, when processing the content of the file, the data must be returned in the form of String to analyze the start and end marks, and also written to the file output stream in the form of byte[] at the same time. */private String readLine(byte[] Linebyte,ServletInputStream servletinputstream, String charset) {try {len = servletinputstream.readLine(Linebyte, 0, Linebyte.length); if (len == -1) {return null; }if (charset == null) {return new String(Linebyte, 0, len); }else {return new String(Linebyte, 0, len, charset); }}catch (Exception _ex) {return null; }}private String getFileName(String line) { //Separate the file name from the description string if (line == null) {return ""; }int i = line.indexOf("filename="); line = line.substring(i + 9).trim(); i = line.lastIndexOf(""); if (i 〈 0 || i 〉= line.length() - 1) {i = line.lastIndexOf("/"); if (line.equals("""")) {return ""; }if (i 〈 0 || i 〉= line.length() - 1) {return line; }}return line.substring(i + 1, line.length() - 1); }private String getKey(String line) { //Separate the field name from the description string if (line == null) {return ""; }int i = line.indexOf("name="); line = line.substring(i + 5).trim(); return line.substring(1, line.length() - 1); }public static String[] split(String strOb, String mark) {if (strOb == null) {return null; }StringTokenizer st = new StringTokenizer(strOb, mark); ArrayList tmp = new ArrayList(); while (st.hasMoreTokens()) {tmp.add(st.nextToken()); }String[] strArr = new String[tmp.size()]; for (int i = 0; i 〈 tmp.size(); i++) {strArr[i] = (String) tmp.get(i); }return strArr; }}Download is actually very simple. As long as you process it as follows, no problem will occur. public void downLoad(String filePath,HttpServletResponse response,boolean isOnLine)throws Exception{File f = new File(filePath); if(!f.exists()){response.sendError(404,"File not found!"); return; }BufferedInputStream br = new BufferedInputStream(new FileInputStream(f)); byte[] buf = new byte[1024]; int len = 0; response.reset(); //It is very important if(isOnLine){ //OnOnOpen Method URL u = new URL("file:///"+filePath); response.setContentType(u.openConnection().getContentType()); response.setHeader("Content-Disposition", "inline; filename="+f.getName()); //The file name should be encoded as UTF-8}else{ //Pure download method response.setContentType("application/x-msdownload"); response.setHeader("Content-Disposition", "attachment; filename=" + f.getName()); }OutputStream out = response.getOutputStream(); while((len = br.read(buf)) 〉0)out.write(buf,0,len); br.close(); out.close(); }