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
<%@ 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>
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~! ~!