基于Servlet实现文件上传&下载

基于Servlet实现文件上传&下载

文件上传是开发中十分常见的功能,要将文件上传至服务端,并可从服务端下载文件到客户端,在servlet3.0之前,实现文件上传需要使用一些插件技术,比如:

  • commons-fileupload
  • smartupload

但是在3.0之后servlet内部集成文件上传的技术(multipart),有关servlet3.0文件上传的实现过程如下:

  1. 表单的提交方式必须设置为post
  2. 表单的enctype必须设置为multipart/form-data(使用二进制流的方式提交数据)
  3. 在servlet类中加上@MultipartConfig注解

1.单文件上传

页面端设置-上传文件(upload.html)





Insert title here


	
	

页面端设置-图片预览(result.jsp)

<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>




Insert title here


	"/>
	
	
	

服务端处理(UploadServlet.java)

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;

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;

/**
 * Servlet implementation class UploadServlet
 */
@WebServlet("/upload")
@MultipartConfig
public class UploadServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
	
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//设置请求编码
		request.setCharacterEncoding("utf-8");
//		String fname = request.getParameter("fname");
//		System.out.println("文件名:"+fname);
		//获取服务端用于存储文件的目录
		String baseDir = request.getServletContext().getRealPath("myfile");
		System.out.println("服务器文件存储路径:"+baseDir);
		
		File f = new File(baseDir);
		if(!f.exists()){
			f.mkdirs();
		}
		
		//获取一个文件单元
		Part part = request.getPart("myfile");
		String type = part.getContentType();
		long size = part.getSize();
		String fname = part.getSubmittedFileName();
		
		System.out.println("文件名称:"+fname);
		System.out.println("文件类型:"+type);
		System.out.println("文件大小:"+size);
		//存储到服务器
		part.write(baseDir + File.separator + fname);
		
		//将文件名称存储到request范围
		request.setAttribute("fname", fname);
		//请求转发到下一个页面中
		request.getRequestDispatcher("result.jsp").forward(request, response);
		
//		
	}
}

2.文件下载

文件下载工具类(FileTools.java)

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;

import javax.servlet.http.HttpServletResponse;

/**
 * 实现文件下载
 * 
 * @author max
 *
 */
public class FileTools {

	public static void download(String path,HttpServletResponse response) throws IOException {
		//根据给定的路径获取文件对象(需要被传输到客户端的文件)
		File file = new File(path);
		String name = file.getName();
		// 1.获取需要传输的文件的输入流
		InputStream is = new FileInputStream(path);
		// 2.获取response对象的输出流
		OutputStream os = response.getOutputStream();

		// 将文件名使用URL编码,防止客户端下载出现乱码
		URLEncoder.encode(name, "utf-8");
		// 设置响应头的响应内容类型:以附件形式发送
		response.setHeader("content-disposition", "attachment;filename=" + name);
		// inline 预览
		// response.setHeader("content-disposition","inline;filename="+name);

		// 3.读取输入流中的内容,并通过输出流输出
		byte[] b = new byte[1024];
		int len = 0;
		while ((len = is.read(b)) != -1) {
			os.write(b, 0, len);
		}
		is.close();
		os.close();
	}

}

3.多文件上传

页面端设置-上传文件(upload2.html)





Insert title here


	

表单中文件控件中指定:multiple属性

页面端设置-文件列表(listfiles.jsp)

<%@page import="java.util.ArrayList"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>




Insert title here


	

文件下载

<% Object obj = request.getAttribute("files"); ArrayList names = (ArrayList)obj; for(String name:names){ %> <%-- --%> <%=name %>
<% } %>

服务端处理-多文件上传(UploadServlet2.java)

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Objects;

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;

/**
 * Servlet implementation class UploadServlet2
 */
@WebServlet({"/UploadServlet2","/upload2"})
@MultipartConfig(
		fileSizeThreshold = 1024*1024,  //设置内存缓存的最大空间(当上传文件的字节数达到该值后使用临时文件缓存)
		location="d:/server/temp",             //设置临时文件的存储目录
		maxFileSize=1024*1024*200,      //设置允许上传的单个文件的最大限制
		maxRequestSize=1024*1024*500    //设置表单允许提交的总字节数
		)
public class UploadServlet2 extends HttpServlet {
	private static final long serialVersionUID = 1L;
    

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}
	
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		request.setCharacterEncoding("utf-8");
		//服务器地址: C:\Users\12483\workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\javaweb04\myfile
//		String base = request.getServletContext().getRealPath("myfile");
		String base = "C:/server/fileserver";
		//声明list集合用于存储文件名称
		ArrayList list = new ArrayList<>();
		//获取所有上传的附件信息
		Collection parts = request.getParts();
		parts.forEach(part->{
			
			String fname = part.getSubmittedFileName();
			String type = part.getContentType();
			long size = part.getSize();
			System.out.println("文件名:"+fname);
			System.out.println("文件类型:"+type);
			System.out.println("文件大小:"+size);
			//只对
			if(!Objects.equals(fname, "null") && Objects.nonNull(fname)){
				//将文件名称存储到集合中
				list.add(fname);
				try {
					part.write(base+File.separator+fname);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
		//将文件名集合存储到request范围
		request.setAttribute("files", list);
		request.getRequestDispatcher("listfiles.jsp").forward(request, response);
		
	}
}

注解@multipartConfig中包含四个可设置的参数,分别为:

  1. fileSizeThreshold 内存缓存的最大空间(当上传文件的字节数达到该值后使用临时文件缓存)
  2. location 临时文件的存储目录
  3. maxFileSize 允许上传的单个文件的最大限制
  4. maxRequestSize 表单允许提交的总字节数

服务器处理-文件下载(DownloadServlet.java)

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;

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

import com.softeem.utils.FileTools;

/**
 * Servlet implementation class DownloadServlet
 */
@WebServlet("/download")
public class DownloadServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
	
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		String name = request.getParameter("fname");
		//获取需要传输到客户端的文件路径
		String path = "c:/server/fileserver"+File.separator + name;
		
		FileTools.download(path, response);
		
	}
}

4.重命名上传文件

页面端设置-上传文件(upload3.html)





Insert title here


	

服务端处理-重命名上传(UploadServlet3.java)

import java.io.File;
import java.io.IOException;
import java.util.Collection;
import java.util.UUID;

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;

/**
 * Servlet implementation class UploadServlet3
 */
@WebServlet("/upload3")
@MultipartConfig
public class UploadServlet3 extends HttpServlet {
	private static final long serialVersionUID = 1L;
      
	
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}
	
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		String basePath = "c:/server/fileserver";
		Collection parts = request.getParts();
		for(Part part:parts){
			//判断上传的是否是文件
			if(part.getSize() > 0){
				//获取上传文件的名称
				String fname = part.getSubmittedFileName();
				//随机产生一个uuid作为文件名称     分布式id生成技术:雪花算法(twitter)
				String uuid = UUID.randomUUID().toString();
				//获取文件的后缀名
				String suffix = fname.substring(fname.lastIndexOf("."));
				//组合uuid和文件后缀成为新的文件名称
				fname = uuid + suffix;
				//将客户端上传的文件写入到服务器指定文件中
				part.write(basePath + File.separator + fname);
			
			}
		}
	}
}

5.上传进度显示

页面端设置(upload4.html)





Insert title here



	

 

你可能感兴趣的:(web后台)