Today, let’s learn about uploading and downloading files, so that we can use them in future projects.

1. File upload

The Apache Commons FILeupload component relies on the Commons IO component to copy files.

The execution process is as follows:

2. File download

The processing process is shown as follows:

Next we will file upload and download the code! , convenient later use oh!

  • Step 1: create a data table (a row in the table data to store two files, for example, including file id, file name, file type, which also can hold title and id of ordinary files, if involves multiple files, you can use a master table, more child table, deposit a one-to-many relationship, the files on a table, the rest of the normal file fields in a table)
CREATE TABLE IF NOT EXISTS upload_info(
	upload_id INT PRIMARY KEY AUTO_INCREMENT,
	title VARCHAR(100),
	file_id_1 VARCHAR(100),
	file_name_1 VARCHAR(100),
	file_type_1 VARCHAR(100),
	file_id_2 VARCHAR(100),
	file_name_2 VARCHAR(100),
	file_type_2 VARCHAR(100)
);
Copy the code
  • Step 2: Write the entity class uploadInfo.java

At this point, a single file class and other file classes are stored separately, with an array to store a single file information

package com.yueqian.store.domain;

public class UploadInfo {
	private int uploadId;
	private String title;
	private FileInfo[] fileInfos = new FileInfo[2];

	public int getUploadId() {
		return uploadId;
	}

	public void setUploadId(int uploadId) {
		this.uploadId = uploadId;
	}

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	public FileInfo[] getFileInfos() {
		return fileInfos;
	}

	public void addFileInfos(int index, FileInfo fileInfo) {
		if(index >= 0 && index < 2) { this.fileInfos[index] = fileInfo; }}}Copy the code

Write the fileInfo. Java

package com.yueqian.store.domain;

public class FileInfo {
	private String fileId;
	private String fileName;
	private String fileType;
	public String getFileId() {
		return fileId;
	}
	public void setFileId(String fileId) {
		this.fileId = fileId;
	}
	public String getFileName() {
		return fileName;
	}
	public void setFileName(String fileName) {
		this.fileName = fileName;
	}
	public String getFileType() {
		return fileType;
	}
	public void setFileType(String fileType) {
		this.fileType = fileType;
	}
	@Override
	public String toString() {
		// TODO Auto-generated method stub
		returnsuper.toString(); }}Copy the code
  • Step 3: Write a JSP (simple test)
<ul>
<li><a href='${pageContext.request.contextPath}/file/upload.jsp'</a></li> <li><a href='${pageContext.request.contextPath}/file/list'> View and download files </a></li> </ul>Copy the code
  • Step 4: Write the servlet

At this point we need to create it in the project directoryTemp directoryIf the number of bytes exceeds the threshold, the file is saved to the hard disk. Otherwise, the file is saved to the memory. The system will automatically generate folders for uploading and saving under the projectUload directory

package com.yueqian.store.controller;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.catalina.util.URLEncoder;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.FileUtils;

import com.yueqian.store.domain.FileInfo;
import com.yueqian.store.domain.UploadInfo;
import com.yueqian.store.service.UploadService;

@WebServlet({ "/file/upload"."/file/download"."/file/list" })
public class FileServlet extends BaseServlet {
	private static final long serialVersionUID = 1L;
	private UploadService uploadService = new UploadService();

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		String uri = req.getRequestURI();
		if (uri.contains("/file/list")) {
			List<UploadInfo> uploadList = this.uploadService.findAllFile();
			req.setAttribute("uploadList", uploadList);
			req.getRequestDispatcher("/file/list.jsp").forward(req, resp);
		} else if (uri.contains("/file/download")) {
			String fileId = super.paseParamter("fileId", req, String.class); File uploadDir = new File(req.getServletContext().getrealPath ()"/upload"));
			if(fileId ! File File = new File(uploadDir, fileId);if (file.exists()) {
					FileInfo fileInfo = this.uploadService.findFileById(fileId);
					if(fileInfo ! Resp.setcontenttype (fileInfo.getFileType()); resp.setContentLengthLong(file.length()); String encodeFileName = null; / / the filename ChengJinXing coding (with url encoding first, and then according to utf-8) encodeFileName = java.net.URLEncoder.encode (the fileInfo. GetFileName (),"UTF-8"); // Content-disposition is set to attachment, which means download as an attachment with user's consent. No file is opened. The default (online) is to open the file browser automatically clock) // also set the real filename when downloading the file //filename*=utf-8' '"+encodeFileName: decodes the encoded Chinese file name (url decode first, utF-8 decode later) // Browsers default to look for this decoding attribute, now the new version of the browser has the encoded Chinese file name decoding default, Resp.setheader ("Content-Disposition","attachment; filename="+encodeFileName+"; filename*=utf-8' '"+encodeFileName); Fileutils.copyfile (file, resp.getOutputStream()); // Save the file to the output stream. } } } } } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {// Check whether the saved File uploadDir exists. If not, create File uploadDir = new File(req.getServletContext().getrealPath ("/upload")); if (! uploadDir.exists()) { uploadDir.mkdirs(); DiskFileItemFactory Factory = new DiskFileItemFactory(); SetSizeThreshold (10240); setSizeThreshold(10240); setSizeThreshold(10240); // 3. Create the disk where the file is stored. (This location can only be obtained from the context path and cannot be accessed by users deployed on Linux elsewhere) The file exceeds the threshold. RealPath = req.getServletContext().getrealPath (")/temp"); System.out.println(realPath + "= = = = = = = = = = = = = = = = = = = = = = = = = = ="); File file = new File(realPath); // repository = factory.setrepository (file); // repository = factory.setrepository (file); ServletFileUpload sfu = new ServletFileUpload(factory); Sfu. setFileSizeMax(5 * 1024 * 1024); Sfu. setSizeMax(10 * 1024 * 1024); // set the ear size for uploading a single file to 5M (2M by default). // Set the total uploaded file size to 10M (the default total file size is 2M) //ServletFileUpload parse request headers for each part of the multi-part form // When the Chinese file name (request header) of the uploaded file is obtained, the decoding format can be set. 8.0 Default UTF-8 sfu.setHeaderEncoding("utf-8"); int count = 0; String exceptionMsg = null; // Record the number of rows affected by saving the file to the database. List
      
        itemList = sfu.parserequest (req); String parthName = null, fileName = null, fileType = null, fileId = null; UploadInfo uploadInfo = null; int index = 0; if (itemList ! = null && itemList.size() > 0) { uploadInfo = new UploadInfo(); For (FileItem item: itemList) {if (item.isformField ()) {parthName = item.getfieldName (); If (" ");
      titleUploadinfo.settitle (item.getString(".equals(parthName)) {// Multi-part form data, each part of the request body values (ordinary file values) decoding method uploadInfo.setTitle(item.getString("UTF-8")); }} else {// Multi-form file (because different browsers, the file name is not the same, as long as the real file name, the front does not need path, FileName = parseFileName(item.getName()); FileId = generateField(); FileType = item.getContentType(); ParthName = item.getfieldName (); InputStream is = item.getinputStream (); // Check whether the upload option is selected. If not, Do not commit (whether input byte size and file name length is equal to 0) if (is. The available () = = 0 | | fileName. The length () = = 0) {continue; } FileOutputStream fos = new FileOutputStream(new File(uploadDir, fileId)); / / get the output stream File / / to save File input stream to a File (implementation) toolbar. / / FileUtils copyInputStreamToFile (is that the new File (uploadDir, fileName)); Byte [] bytes = new byte[1024]; int len = 0; while (-1 ! = (len = is.read(bytes))) { fos.write(bytes, 0, len); } fos.close(); is.close(); FileInfo fileInfo = new FileInfo(); fileInfo.setFileId(fileId); fileInfo.setFileName(fileName); fileInfo.setFileType(fileType); uploadInfo.addFileInfos(index++, fileInfo); }} / / the information stored in the database count = this. UploadService. SaveInfo (uploadInfo); } } catch (FileUploadException e) { e.printStackTrace(); } resp.sendRedirect(req.getContextPath() + "/file/upload.jsp? count=" + count); // Redirect to upload file page}}Copy the code
  • Step 3: Write the Service
package com.yueqian.store.service; import java.sql.SQLException; import java.util.List; import com.yueqian.store.common.DBUtils; import com.yueqian.store.dao.UploadDao; import com.yueqian.store.domain.FileInfo; import com.yueqian.store.domain.UploadInfo; /** * save file * @author LinChi
 *
 */
public class UploadService {
	private UploadDao uploadDao = new UploadDao();
	public int saveInfo(UploadInfo uploadInfo) {
		int count = 0;
		try {
			count = this.uploadDao.saveInfo(uploadInfo);
			DBUtils.commit();
		}catch(SQLException e) {
			DBUtils.rollback();
			e.printStackTrace();
		}
		returncount; } /** * query all file list * @return
	 */
	public List<UploadInfo> findAllFile(){
		List<UploadInfo> list = null;
		try {
			list = this.uploadDao.findAllFile();
			DBUtils.commit();
		}catch(Exception e) {
			DBUtils.rollback();
			e.getStackTrace();
		}
		returnlist; } /** * view file information based on fileId * @param fileId * @return
	 */
	public FileInfo findFileById(String fileId) {
		FileInfo info = null;
		try {
			info = this.uploadDao.findFileById(fileId);
			DBUtils.commit();
		}catch(Exception e) {
			DBUtils.rollback();
			e.getStackTrace();
		}
		returninfo; }}Copy the code
  • Step 5: Write the DAO
package com.yueqian.store.dao; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Types; import java.util.ArrayList; import java.util.List; import com.yueqian.store.common.DBUtils; import com.yueqian.store.domain.FileInfo; import com.yueqian.store.domain.UploadInfo; /** * public class UploadDao {public int saveInfo(UploadInfo UploadInfo) throws SQLException {  Connection conn = DBUtils.getConnection(); PreparedStatement pstm = null; int count = 0; try { pstm = conn.prepareStatement("INSERT INTO upload_info(title,file_id_1,file_name_1,file_type_1,file_id_2,file_name_2,file_type_2) VALUES(? ,? ,? ,? ,? ,? ,?) ");
			pstm.setString(1, uploadInfo.getTitle());
			if(uploadInfo.getFileInfos()[0] ! = null) { pstm.setString(2, uploadInfo.getFileInfos()[0].getFileId()); pstm.setString(3, uploadInfo.getFileInfos()[0].getFileName()); pstm.setString(4, uploadInfo.getFileInfos()[0].getFileType()); }else {
				pstm.setNull(2, Types.VARCHAR);
				pstm.setNull(3, Types.VARCHAR);
				pstm.setNull(4, Types.VARCHAR);
			}
			if(uploadInfo.getFileInfos()[1] ! = null) { pstm.setString(5, uploadInfo.getFileInfos()[1].getFileId()); pstm.setString(6, uploadInfo.getFileInfos()[1].getFileName()); pstm.setString(7, uploadInfo.getFileInfos()[1].getFileType()); }else {
				pstm.setNull(5, Types.VARCHAR);
				pstm.setNull(6, Types.VARCHAR);
				pstm.setNull(7, Types.VARCHAR);
			}
			count = pstm.executeUpdate();
		} finally {
			DBUtils.close(null, pstm);
		}
		returncount; } /** * query all file list ** @return
	 * @throws SQLException
	 */
	public List<UploadInfo> findAllFile() throws SQLException {
		Connection conn = DBUtils.getConnection();
		PreparedStatement pstm = null;
		ResultSet rs = null;
		List<UploadInfo> list = new ArrayList<UploadInfo>();
		UploadInfo uploadInfo = null;
		try {
			pstm = conn.prepareStatement(
					"SELECT u.`upload_id`,u.`title`,u.`file_id_1`,u.`file_name_1`,u.`file_type_1`,u.`file_id_2`,u.`file_name_2`,u.`file_type_2`\r\n"
							+ "FROM upload_info u");
			rs = pstm.executeQuery();
			String fileName;
			while (rs.next()) {
				uploadInfo = new UploadInfo();
				uploadInfo.setUploadId(rs.getInt(1));
				uploadInfo.setTitle(rs.getString(2));
				fileName = rs.getString("file_name_1");
				if(fileName ! = null) { FileInfo fileInfo = new FileInfo(); fileInfo.setFileId(rs.getString(3)); fileInfo.setFileName(rs.getString(4)); fileInfo.setFileType(rs.getString(5)); uploadInfo.addFileInfos(0, fileInfo); } fileName = rs.getString("file_name_2");
				if(fileName ! = null) { FileInfo fileInfo = new FileInfo(); fileInfo.setFileId(rs.getString(6)); fileInfo.setFileName(rs.getString(7)); fileInfo.setFileType(rs.getString(8)); uploadInfo.addFileInfos(1, fileInfo); } list.add(uploadInfo); } } finally { DBUtils.close(rs, pstm); }returnlist; } /** * View file information based on the file ID ** @return
	 * @throws SQLException
	 */
	public FileInfo findFileById(String fileId) throws SQLException {
		Connection conn = DBUtils.getConnection();
		PreparedStatement pstm = null;
		FileInfo fileInfo = null;
		ResultSet rs = null;
		try {
			pstm = conn.prepareStatement("SELECT u1.file_id_1,u1.file_name_1,u1.file_type_1 FROM upload_info u1 WHERE u1.file_id_1=? UNION SELECT u2.file_id_2,u2.file_name_2,u2.file_type_2 FROM upload_info u2 WHERE u2.file_id_2=?");
			pstm.setString(1, fileId);
			pstm.setString(2, fileId);
			rs = pstm.executeQuery();
			if (rs.next()) {
				fileInfo = new FileInfo();
				fileInfo.setFileId(rs.getString(1));
				fileInfo.setFileName(rs.getString(2));
				fileInfo.setFileType(rs.getString(3));
			}
		} finally {
			DBUtils.close(rs, pstm);
		}
		returnfileInfo; }}Copy the code
  • Step 6: Write the upload.jsp file
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"% > <! DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> File upload </title> </head> <body> <h2> File upload </h2> <form action="<%=request.getContextPath()%>/file/upload" method="post" enctype = "multipart/form-data"< span style = "box-sizing: border-box! Importanttype="text" name="title"><br/> File 1: <inputtype="file" name="attachment"><br/> File 2: <inputtype="file" name="attachment"><br/>
		<input type="submit" value = "Submit">
		<%
			String count = request.getParameter("count");
			if(count ! = null && count.length()>0){ int fileCount = Integer.parseInt(count);if(fileCount>0){
					out.print("Successfully uploaded."+fileCount+"File!");
				}else{
					out.print("Upload file failed!");
				}
			}
			
		%>
</form>
</body>
</html>
Copy the code
  • Step 7: Write list.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="java.util.*,com.yueqian.store.domain.*"% > <! DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> File view List< /title> </head> <body> <h2> File upload List< /h2> <% List<UploadInfo> List = (List<UploadInfo>)request.getAttribute("uploadList");
	list.forEach(System.out::print);
	if(list ! = null && list.size()>0){ %> <ul> <%for(UploadInfo info: list) {% > < li > title: < % = info. The getTitle () % > < br / > < %if(info.getFileInfos()[0]! =null){ %> <a href="<%=request.getContextPath()%>/file/download? fileId=<%=info.getFileInfos()[0].getFileId()%>"><%=info.getFileInfos()[0].getFileName() %></a><br/>
			<%} %>
			<% if(info.getFileInfos()[1]! =null){ %> <a href="<%=request.getContextPath()%>/file/download? fileId=<%=info.getFileInfos()[1].getFileId()%>"><%=info.getFileInfos()[1].getFileName() %></a>
			<%} %>
		</li>
		<%} %>
	</ul>
	<%} %>
</body>
</html>
Copy the code
  • Other database utility classes
package com.yueqian.store.common;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.HashMap;
import java.util.Map;

import org.apache.tomcat.dbcp.dbcp2.BasicDataSource;

public class DBUtils {
	private static final String URL = "JDBC: mysql: / / 127.0.0.1:3306 / store? useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&useSSL=false";
	private static final String USERNAME = "root";
	private static final String PASSWORD = "xxx";
	private static BasicDataSource ds = null;
	public static void init() {/ / the load Driver try {/ / a DriverManager. RegisterDriver (. New com. Mysql. Cj. JDBC Driver ()); // Class.forname ()"com.mysql.cj.jdbc.Driver()"); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } // create a database connection pool ds = new BasicDataSource(); // Set connection information ds.setDriverclassName ("com.mysql.cj.jdbc.Driver"); ds.setUrl(URL); ds.setUsername(USERNAME); ds.setPassword(PASSWORD); Ds.setmaxidle (30); // Set the connection pool information. // Minimum number of free connections ds.setminIdle(2); // Set the initial connection number ds.setInitialSize(2); Ds.setmaxwaitmillis (4000); Ds.setdefaultautocommit (ds.setDefaultautoCommit)false); } // add a thread object to the ThreadLocal class, and use the current thread object as the key to store the conn object. Private static ThreadLocal<Connection> ThreadLocal = new ThreadLocal<Connection>(); /** * connect to database ** @return
	 */
	public static Connection getConnection() {// Get the connection from a threadLocal, which is similar to a map, with the key as the current thread object and the value as conn connection. Connection conn = threadLocal.get(); // If the connection is null, get the connection from the connection poolif(conn == null) { try { conn = ds.getConnection(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } // Set the resulting connection to threadLocal threadlocal.set (conn); }returnconn; } public static void close(ResultSet rs, Statement STMT) {} public static void close(ResultSet rs, Statement STMT) {if(rs ! = null) { try { rs.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally {if(stmt ! = null) { try { stmt.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); }}}}} // Commit transaction public static voidcommit() {
		Connection conn = threadLocal.get();
		if(conn ! = null){ try { conn.commit(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally {// Close the connection try {conn.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } // Clean up threadlocal.remove (); }}} // Rollback transaction public static voidrollback() {
		Connection conn = threadLocal.get();
		if(conn ! = null){ try { conn.rollback(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally {// Close the connection try {conn.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } // Clean up threadlocal.remove (); }} /** * Close the database connection pool */ public static voidcloseDataSourse() {
		if(ds ! = null) { try { ds.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); }}}}Copy the code

Fast file replication is implemented in the traditional way

A:

InputStream is = item.getInputStream(); FileOutputStream fos = new FileOutputStream(new File(uploadDir, fileId)); Byte [] bytes = new byte[1024]; int len = 0;while(1! = (len = is.read(bytes))) { fos.write(bytes, 0, len); } fos.close(); is.close();Copy the code

Please refer to another IO blog: juejin.cn/post/684490…

Method 2: Use the Commons IO component file utility class to quickly copy files

/ / to save File input stream to a File (implementation) toolbar FileUtils. CopyInputStreamToFile (is that the new File (uploadDir, fileName)); Fileutils.copyfile (file, resp.getOutputStream()); // Save the file to the output stream.Copy the code

In this project, we learned about file upload and copy, implemented in two ways, not forgetting the basic operation of IO, but also using the tool class for fast file copy. Get to the small partners like 👍+ pay attention to it!!