Teach you how to play with the details of file upload and download in J2EE

     Description: Regarding the problem of file uploading and downloading, I have actually written several articles on how to deal with different situations. This article is mainly aimed at how to use convenient skills to complete this function in J2EE, and it is very important for many of the Detailed knowledge, a very detailed description, please pay more attention to the content of the notes. If necessary, read the other articles for more in-depth study.

Article 1: http://blog.csdn.net/Cs_hnu_scw/article/details/78755519

Article 2: http://blog.csdn.net/Cs_hnu_scw/article/details/77929869

One: file upload

Knowledge point 1: single file upload processing

Method 1: Through Apache related packages

Development steps:

(1) Guide package:


(2) JSP page:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Upload file</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/uploadservlet" method="post" enctype="multipart/form-data">
文件描述:<input type="text" name="description">
<input type="file" name="uploadfile">
<input type="submit" value="上传">
</form>

</body>
</html>

(3) servlet code

package com.hnu.scw.upload.demo1;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
import java.util.UUID;
import javax.naming.SizeLimitExceededException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadBase.FileSizeLimitExceededException;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.ProgressListener;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.IOUtils;
import sun.security.jca.GetInstance.Instance;

/**
 * demo1 for file upload
 * @author scw
 *
 */
public class UploadFileDemo1 extends HttpServlet {

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doPost(request, response);
	}

	
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		/ / Solve the problem of garbled files
		request.setCharacterEncoding("utf-8");
		
		//1: Create a factory class instance object for file upload
		DiskFileItemFactory diskFileItemFactory = new DiskFileItemFactory();
		
		//In order to improve the efficiency of uploading large files, a temporary directory is added here, which is placed in the tmp under WEB-INF, of course, it can also be placed outside WEB-INF.
		diskFileItemFactory.setRepository(new File("WEB-INF/tmp"));
		diskFileItemFactory.setSizeThreshold(1024*1024*3);
		
		
		//2: Create a servletFileUpload instance object for file upload
		ServletFileUpload servletFileUpload = new ServletFileUpload(diskFileItemFactory);
		// Parse the content of the request object
		try {
			//Set the file upload size limit
			servletFileUpload.setFileSizeMax(1024*1024*3); //A single file cannot exceed 3M
			servletFileUpload.setSizeMax(1024*1024*10); //The total upload file size cannot exceed 10M
			
			/ / Implement the server-side implementation of the simulated progress bar function
			//(1) Get the upload time
			long startTime = System.currentTimeMillis();
			//(2) Implement progress bar listener
			servletFileUpload.setProgressListener(new ProgressListener() {
				/**
				 * The first parameter: the size that has been uploaded
				 * The second parameter: the total size
				 * The third parameter: the order of the files in the upload tag, this has no effect
				 */
				@Override
				public void update(long alreadloadsize, long totalsize, int formnumber) {
					//get current time
					long currentTime = System.currentTimeMillis();
					//calculate the elapsed time
					long useTime = currentTime - startTime;
					//Calculate the upload speed
					long speed  = alreadloadsize / useTime ;
					//Calculate the remaining unuploaded size
					long unloadsize = totalsize - alreadloadsize;
					//Calculate the time that still needs to be uploaded
					long nextTime = unloadsize / speed  ;
					System.out.println("Time spent: " + useTime);
					System.out.println("Upload speed: " + speed );
					System.out.println("Remaining size: " + unloadsize);
					System.out.println("Remaining time: " + nextTime);				
				}
			});
			
			
			List<FileItem> parseRequest = servletFileUpload.parseRequest(request);
			//4: Traverse the content
			for (FileItem fileItem : parseRequest) {
				//If it is true, it means that the current content data obtained is not the content of the uploaded file, and if it returns false, it means the content of the uploaded file
				if(fileItem.isFormField()){
					//Get the content of the name attribute of the JSP corresponding tag
					String fieldName = fileItem.getFieldName();
					//Get the content of the JSP corresponding tag value, and solve the problem of Chinese garbled characters
					String value = fileItem.getString("utf-8");
					System.out.println(fieldName + "@" + value);
				}else{
					/ / Get the uploaded file, the name of the uploaded file
					String name = fileItem.getName();
					//In order to solve the problem that when some browsers (such as IE6) upload files, the upload file name is the entire path, such as C:\\upload\file\aa.txt, so it needs to be handled specially,
					//But generally this problem does not exist at present, mainly for some old browsers
					int index = name.lastIndexOf("\\");
					//If the matched index is greater than or equal to 0, it means that it needs to be intercepted, because if it does not match, it will return -1
					if(index >= 0){
						name = name.substring(index+1 , name.length());
					}
					//In order to prevent, if the uploaded file name is the same, then the previous one will be replaced, so it needs to be specially dealt with here (of course, the timestamp is also OK)
					name = UUID.randomUUID().toString() + name;
					//Get the byte stream content of the uploaded file
					InputStream inputStream = fileItem.getInputStream();
					//Get the path where the uploaded content is stored
					//If the upload path is to be placed outside the web-inf directory, it should be in the following form
					String realPath = getServletContext().getRealPath("/demo1path");
					//If you want to put it in the web-inf directory, the following form is recommended, because this way you can't directly access the content in this directory from the browser, which is more secure
					//String realPath = getServletContext().getRealPath("WEB-INF/demo1path");
					//Create a file path to prevent abnormal problems when the directory does not exist
					if(!new File(realPath).exists()){
						new File(realPath).mkdirs();
					}
					//Create an output stream, here we use a buffered output stream to improve the efficiency of uploading
					OutputStream os =new BufferedOutputStream( new FileOutputStream(new File(realPath , name)));				
					//For upload processing, use a method in the commons.io.jar package, which is more convenient than general processing
					IOUtils.copy(inputStream, os);
					
					//Delete the content in the temporary directory, which is also due to the temporary directory added before to improve upload efficiency
					fileItem.delete();
					//close the resource
					inputStream.close();
					os.close();
				}
			}
			
		} catch (Exception e) {
			/ / Grab a single file upload size exceeds the limit
			if(e instanceof FileSizeLimitExceededException){
				System.out.println("Single file is too big~~~~~~~~~~~");
			}
			// Grab and upload multiple files The upload size exceeds the limit
			if(e instanceof SizeLimitExceededException){
				System.out.println("Total upload file is too big~~~~~~~~~~~~");
			}
			e.printStackTrace ();
		}
		
		
	}

}

(4) Project directory


Knowledge point 2: Multiple file upload processing

JSP page: (background processing is the same as the single upload above, but it must be ensured that the name of the <input> attribute must be consistent)

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Dynamic multi-file upload</title>
</head>
<script type="text/javascript">
	//Add the number of frames for file upload
	function addFileItem() {
		document.getElementById("filediv").innerHTML +="<div><input type='file' name='uploadfile'><input type='button' onclick='deleteFileItem(this)' value='删除'></div>"
	}
	//Delete the number of frames for file upload
	function deleteFileItem(currentbtn){
		var divbtn = currentbtn.parentNode;
		divbtn.parentNode.removeChild(divbtn);
	}
</script>
<body>
<form action="${pageContext.request.contextPath}/uploadservlet" method="post" enctype="multipart/form-data">
	<input type="button" id ="addfile" onclick="addFileItem()" value="添加上传文件">
	<div id="filediv">
	</div>
	<input type="submit" value="上传">
</form>
</body>
</html>

Method 2: Through the method that comes with the servlet

JSP code:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    
    <title>File upload page</title>
    
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="cache-control" content="no-cache">
	<meta http-equiv="expires" content="0">    
	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
	<meta http-equiv="description" content="This is my page">
	<!--
	<link rel="stylesheet" type="text/css" href="styles.css">
	-->

  </head>
  
  <body>
    <form action="${pageContext.request.contextPath}/upload" method="post" enctype="multipart/form-data">
    	<input type="text" name="filetext"><br>
    	<input type="file" name="upload"><br>
    	<input type="submit" value="上传">
    </form>
  </body>
</html>

servlet code: (configuration is done through annotations)
package com.hnu.scw.upload.demo3;
import java.io.IOException;
import java.io.InputStream;
import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;
@WebServlet(urlPatterns={"/upload"})
@MultipartConfig(
	fileSizeThreshold=1024*1024*3, // Set the cache size
	maxFileSize=1024*1024*3, // Set the upload single file size
	maxRequestSize=1024*1024*10 // Set the total upload size
)
public class UploadFileDemo3 extends HttpServlet{
	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		doPost(request, response);
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		// How to handle file upload logic: Part interface
		request.setCharacterEncoding("utf-8");
		
		/*
		 * 1 How to get the normal item of file upload?
		 * * Ordinary items that can be uploaded through the getParameter(String name) method of the Request object.
		 * * name parameter: Specify the name attribute value of the common item uploaded on the client page.
		 */
		String filetext = request.getParameter("filetext");
		
		/*
		 * 2 How to get the instance object of the Part interface?
		 * * The instance object of the Part interface can be obtained through the getPart(String name) method of the Request object.
		 * * name parameter: Specify the name attribute value of the upload file domain of the client page.
		 * * Get the name of the file upload item and the file input stream through the instance object of the Part interface.
		 * * The write(filename) method provided by the Part interface:
		 * * Write the received file input stream to the specified server-side directory.
		 * * Parameter filename: The absolute path of the specified save file.
		 * * Part interface provides getName() method:
		 * * Gets the value of the name attribute of the uploaded file domain.
		 * * Does not get the real uploaded file name.
		 * * How to get the real file name uploaded?
		 ** Servlet 3.0 has been criticized for completing the file upload function.
		 *    *
		 */
		Part part = request.getPart("upload");
		/*String filename = part.getName();
		System.out.println(filename);*/
		
		/*
		 * Get the real file name uploaded:
		 *  Content-Disposition: form-data; name="upload"; filename="readme.txt"
		 */
		String header = part.getHeader("Content-Disposition");
		int index = header.lastIndexOf("filename=\"");
		String filename = header.substring(index+10, header.length()-1);
		
		InputStream in = part.getInputStream();
		String realPath = getServletContext().getRealPath("/uploads");
		part.write(realPath+"/"+filename);
	}
}

Two: file download

step:

(1) JSP (simulate the list of files that need to be downloaded)

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>File download processing</title>
</head>
<body>
<h1>The list of downloads is as follows:</h1>
<a href="${pageContext.request.contextPath}/downfile?filename=1.et">下载1.et</a>
<a href="${pageContext.request.contextPath}/downfile?filename=2.txt">下载2.txt</a>
</body>
</html>

(2) servlet code

package com.hnu.scw.filedown.demo2;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.catalina.util.Base64;
import org.apache.commons.io.IOUtils;

import sun.misc.BASE64Encoder;
/**
 * Handle file downloads
 * @author scw
 *
 */
public class FileDownDemo extends HttpServlet {

	/**
	 * Because the a tag is used directly in the JSP, the request processing is performed in the Get method.
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//1: Get the name of the file to download
		String fileName = request.getParameter("filename");
		//In order to prevent the problems caused by Chinese garbled characters, we need to deal with them
		fileName = new String(fileName.getBytes("ISO-8859-1"),"UTF-8");
		//2: Then according to the file name, go to the database to find the corresponding storage location (there is no database operation here, just simulate it)
		String downPath = "";
		//If the file name to be downloaded is 2.txt, then go to the middle path of the corresponding project under the path tomcat to find it. I put it in the downfilepath file directory here: find
		if("2.txt".equals(fileName)){
			downPath = "D:\\apache-tomcat-7.0.70\\webapps\\UploadFileServletProject\\downfilepath\\2.txt";
		}
		//If the file name to be downloaded is 1.et, then go to the path: find
		else if("1.et".equals(fileName)){
			downPath = "D:\\apache-tomcat-7.0.70\\webapps\\UploadFileServletProject\\downfilepath\\1.et";
		}
		//------------The above path should be searched in the database in actual development, the above is just a simulation -----------------
		//3: Get the input stream
		FileInputStream io = new FileInputStream(new File(downPath));
		
		//-----The following is to solve the problem that when there is Chinese in the downloaded file name, if it is not processed when displayed, the Chinese content will not be displayed---------
		    //Mainly deal with IE and other browsers separately
		String header = request.getHeader("User-Agent");
		if(header.contains("MSIE")){
			//Indicates that it is an IE browser
			fileName = URLEncoder.encode(fileName);
			fileName = fileName.replace("+", " ");
		}else{
			// is another type of browser
			 BASE64Encoder base64Encoder = new BASE64Encoder();
			 //This is the fixed way of handling
			 fileName = "=?utf-8?B?" + base64Encoder.encode(fileName.getBytes("utf-8")) + "?=";
		}
		//-------Processing ends -----------------------
		
		//4: The setting tells the browser to download as a file download (if it is not specified, the browser will not download it, so there is a problem)
		response.setContentType(getServletContext().getMimeType(fileName));
		response.setHeader("Content-Disposition", "attachment;filename="+fileName);
		//5: Get the input stream
		OutputStream os = response.getOutputStream();
		//6: Download processing
		IOUtils.copy(io, os);
		//7: close the resource
		io.close();
		os.close();
		
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}

}
The project structure that integrates file upload and download looks like this:


   If you analyze it step by step, in fact, it is not very copying for file processing, and the process logic is still very clear. In addition, for the processing of different other situations, please check the other articles mentioned above~! ~!

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325583241&siteId=291194637