文件上传和下载

本例相关的 jar 包:

/file_demo/WebRoot/WEB-INF/lib/commons-fileupload-1.3.1.jar
/file_demo/WebRoot/WEB-INF/lib/commons-io-2.4-sources.jar
/file_demo/WebRoot/WEB-INF/lib/commons-io-2.4.jar
/file_demo/WebRoot/WEB-INF/lib/commons-lang3-3.1-sources.jar
/file_demo/WebRoot/WEB-INF/lib/commons-lang3-3.1.jar
/file_demo/WebRoot/WEB-INF/lib/jstl.jar
/file_demo/WebRoot/WEB-INF/lib/standard.jar

自定义标签库:

/file_demo/WebRoot/WEB-INF/c.tld

文件上传的 JSP 页面:

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


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
	<head>
		<title>图片上载</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">

	</head>

	<body>
		<form action="UploadImagesServlet" method="post" enctype="multipart/form-data">
			<input type="file" name="image"  />
			<input type="submit" value="保存" />
		</form>
	</body>
</html><span style="font-size:18px;">
</span>

 

文件上传的 UploadImagesServlet :

package com.shanghai.v7.upload;

import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.UUID;

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.FileItemFactory;
import org.apache.commons.fileupload.FileUploadBase;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

/**
 * Servlet implementation class uploadImageServlet
 */
public class UploadImagesServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	/**
	 * @see HttpServlet#HttpServlet()
	 */
	public UploadImagesServlet() {
		super();
		// TODO Auto-generated constructor stub
	}

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doGet(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		this.doPost(request, response);
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		// 响应乱码处理
		response.setContentType("text/html;charset=UTF-8");
		
		//得到上传文件的保存目录,将上传的文件存放于WEB-INF目录下,不允许外界直接访问,保证上传文件的安全
		String path = this.getServletContext().getRealPath("/WEB-INF/upload");
		
		
		/*ServletContext application = this.getServletContext();
		String path = application.getRealPath("uploadImg"); // 要注意如何得到tomcat动态路径
		 */		
		System.out.println(path);
		
		//使用Apache文件上传组件处理文件上传步骤:
		//1、创建一个DiskFileItemFactory工厂
		FileItemFactory factory = new DiskFileItemFactory();
		//2、创建一个文件上传解析器
		ServletFileUpload upload = new ServletFileUpload(factory);
		//解决上传文件名的中文乱码
		upload.setHeaderEncoding("UTF-8");
		 //3、判断提交上来的数据是否是上传表单的数据
        if(!ServletFileUpload.isMultipartContent(request)){
            //按照传统方式获取数据
            return;
        }
		//设置单个文件的最大限制 5m
        upload.setSizeMax(1024*1024*50); // 单位为byte
		//消息提示
		String message = "";
		try {
			 //4、使用ServletFileUpload解析器解析上传数据,解析结果返回的是一个List<FileItem>集合,每一个FileItem对应一个Form表单的输入项
			List<FileItem> list = upload.parseRequest(request);// 解析界面中的输入框
			for (FileItem fileItem : list) {
				//5、如果fileitem中封装的是普通输入项的数据
				if (fileItem.isFormField()) { // 普通表单字段
					String name = fileItem.getFieldName();
                    //解决普通输入项的数据的中文乱码问题
                    String value = fileItem.getString("UTF-8");
                    //value = new String(value.getBytes("iso8859-1"),"UTF-8");
                    System.out.println(name + "=" + value);
				} else {
					//6、如果fileitem中封装的是上传文件
                    //得到上传的文件名称
					String fileName = fileItem.getName();
					if(fileName==null || fileName.trim().equals("")){
                        continue;
                    }
					List<String> fileTypes = Arrays.asList("gif", "bmp", "jpg", "jpeg");// 定义允许上载文件格式
					String fileExtName = fileName.substring(fileName.lastIndexOf(".") + 1); // 得到上载文件的后缀名
					if (fileTypes.contains(fileExtName)) { // 判断文件类型是否在允许范围内
						//按日期生成文件夹
						String filedate = FilenameUtils.MONTH_FORMAT.format(new Date());
						File file = new File(path+filedate);
						//如果文件不存在
						if(!file.exists()){
							file.mkdirs();
						}
						String randomName =UUID.randomUUID().toString().replaceAll("-", "");//随机产生32位,为文件名重命名
						fileName=randomName+fileName;
						//7、流复制到path目录
						fileItem.write(new File(file+ File.separator+fileName));
						//删除处理文件上传时生成的临时文件
						fileItem.delete();
						//获取item中的上传文件的输入流
                        /*InputStream in =  null;
                        BufferedInputStream bis = null;
                        //创建一个文件输出流
                        FileOutputStream out = null;
                        BufferedOutputStream bos = null;
                        try {
                        	in = fileItem.getInputStream();
                        	
                        	bis = new BufferedInputStream(in);
                        	
                        	out = new FileOutputStream(path+ File.separator+fileName);
                        	
                        	bos = new BufferedOutputStream(out);
                        	//判断输入流中的数据是否已经读完的标识
                            int len = 0;
                            //创建一个缓冲区
                            byte buffer[] = new byte[bis.available()];
                            //循环将输入流读入到缓冲区当中,(len=in.read(buffer))>0就表示in里面还有数据
                            while((len=bis.read(buffer))>0){
                            	bos.write(buffer, 0, len);
                            }
						} catch (IOException e) {
							throw new RuntimeException("IO 异常!");
						} finally {
							if(bos!=null){
								bos.close();
							}
							if(out!=null){
	                            //关闭输出流
								out.close();
							}
							if(bis!=null){
								bis.close();
							}
							if(in!=null){
	                            //关闭输入流
								in.close();
							}
							if(fileItem!=null){
								//删除处理文件上传时生成的临时文件
								//fileItem.delete();
							}
						}*/
                        message = "文件上传成功!";

					} else {
						message = "上传失败,文件类型只能是gif、bmp、jpg、jpeg";
					}
				}
			}
		} catch (FileUploadBase.SizeLimitExceededException e) {
			message = "上传失败,文件太大,单个文件的最大限制是:" + upload.getSizeMax() + "  byte!  ;实际上载文件的大小为:  ";
		} catch (Exception e) {
			 message= "文件上传失败!";
			 e.printStackTrace();
		}
		request.setAttribute("message",message);
        request.getRequestDispatcher("/message.jsp").forward(request, response);
	}

}


文件名生成帮助类

package com.shanghai.v7.upload;

import java.io.File;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.apache.commons.lang3.RandomStringUtils;



/**
 * @Description: 文件名生成帮助类
 * @author 
 * @date 2014-11-13 下午04:31:01
 * @version V1.0
 */
public abstract class FilenameUtils {

	/**
	 * 日期格式化对象,将当前日期格式化成yyyyMM格式,用于生成目录。
	 */
	public static final DateFormat pathDf = new SimpleDateFormat("yyyyMM");

	/**
	 * 日期格式化对象,将当前日期格式化成ddHHmmss格式,用于生成文件名。
	 */
	public static final DateFormat nameDf = new SimpleDateFormat("ddHHmmss");

	/**
	 * 36个小写字母和数字
	 */
	public static final char[] N36_CHARS = { '0', '1', '2', '3', '4', '5', '6',
			'7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
			'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
			'x', 'y', 'z' };

	public static final DateFormat MONTH_FORMAT = new SimpleDateFormat("/yyyyMM/dd");

	/**
	 * 生成当前年月格式的文件路径
	 * 
	 * yyyyMM 200806
	 * 
	 * @return
	 */
	public static String genPathName() {
		return pathDf.format(new Date());
	}

	/**
	 * 生产以当前日、时间开头加4位随机数的文件名
	 * 
	 * ddHHmmss 03102230
	 * 
	 * @return 10位长度文件名
	 */
	public static String genFileName() {
		return nameDf.format(new Date()) + RandomStringUtils.random(4, N36_CHARS);
	}

	/**
	 * 
	* @Description: 根据文件路径及后缀名产生文件名  如/base/201412/10082804aia5.gif
	* @author 
	* @date 2014-12-10 上午08:27:02 
	* @version V1.0
	 */
	public static File generateFilename(File path, String ext) { 
		String fileName= RandomStringUtils.random(4, FilenameUtils.N36_CHARS) + "." + ext;
		return new File(path,fileName);
	}

	/**
	 * 生产以当前时间开头加4位随机数的文件名
	 * 
	 * @param ext
	 *            文件名后缀,不带'.'
	 * @return 10位长度文件名+文件后缀
	 */
	public static String genFileName(String ext) {
		return genFileName() + "." + ext;
	}

	/**
	 * 
	 * @Description: 获得文件的后缀名
	 * @author 
	 * @param fileName
	 *            文件名
	 * @date 2014-11-13 下午04:32:24
	 * @version V1.0
	 */

	public static String getFileSufix(String fileName) {
		int splitIndex = fileName.lastIndexOf(".");
		return fileName.substring(splitIndex + 1);
	}

	public static void main(String[] args) {
		System.out.println(genPathName());
		System.out.println(genFileName());
	}
}


 

 

跳转 文件 列表 的ListFileServlet:

package com.shanghai.v7.downlad;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

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

@SuppressWarnings("serial")
public class ListFileServlet extends HttpServlet {

	/**
	 * The doGet method of the servlet. <br>
	 * 
	 * This method is called when a form has its tag value method equals to get.
	 * 
	 * @param request
	 *            the request send by the client to the server
	 * @param response
	 *            the response send by the server to the client
	 * @throws ServletException
	 *             if an error occurred
	 * @throws IOException
	 *             if an error occurred
	 */
	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		this.doPost(request, response);
	}

	/**
	 * The doPost method of the servlet. <br>
	 * 
	 * This method is called when a form has its tag value method equals to
	 * post.
	 * 
	 * @param request
	 *            the request send by the client to the server
	 * @param response
	 *            the response send by the server to the client
	 * @throws ServletException
	 *             if an error occurred
	 * @throws IOException
	 *             if an error occurred
	 */
	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		//System.out.println("======================>");
		// 获取上传文件的目录
		String uploadFilePath = this.getServletContext().getRealPath("/WEB-INF/upload");
		// 存储要下载的文件名
		Map<String, String> fileNameMap = new HashMap<String, String>();
		// 递归遍历filepath目录下的所有文件和目录,将文件的文件名存储到map集合中
		listfile(new File(uploadFilePath), fileNameMap);// File既可以代表一个文件也可以代表一个目录
		// 将Map集合发送到listfile.jsp页面进行显示
		request.setAttribute("fileNameMap", fileNameMap);
		request.getRequestDispatcher("/listfile.jsp").forward(request, response);

	}

	public void listfile(File file, Map<String, String> map) {
		// 如果file代表的不是一个文件,而是一个目录
		if (!file.isFile()) {
			// 列出该目录下的所有文件和目录
			File files[] = file.listFiles();
			// 遍历files[]数组
			for (File f : files) {
				// 递归
				listfile(f, map);
			}
		} else {
			/**
			 * 处理文件名,上传后的文件是以uuid_文件名的形式去重新命名的,去除文件名的uuid_部分
			 * file.getName().indexOf("_")检索字符串中第一次出现"_"字符的位置,如果文件名类似于:9349249849-88343-8344_阿_凡_达.avi
			 * 那么file.getName().substring(file.getName().indexOf("_")+1)处理之后就可以得到阿_凡_达.avi部分
			 */
			String realName = file.getName().substring(file.getName().indexOf("_") + 1);
			// file.getName()得到的是文件的原始名称,这个名称是唯一的,因此可以作为key,realName是处理过后的名称,有可能会重复
			map.put(file.getName(), realName);
		}
	}
}


 

上传后文件列表界面:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE HTML>
<html>
	<head>
		<title>下载文件显示页面</title>
	</head>

	<body>
		<!-- 遍历Map集合 -->
		<c:forEach var="me" items="${fileNameMap}">
			<c:url value="/DownLoadServlet" var="downurl">
				<c:param name="filename" value="${me.key}"></c:param>
			</c:url>
			<img src="${downurl}" width="150px" height="100px" />
        	${me.value}<a href="${downurl}">下载</a>
			<br />
		</c:forEach>
	</body>
</html>


 

下载的DownLoadServlet

package com.shanghai.v7.downlad;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.Date;

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

import com.shanghai.v7.upload.FilenameUtils;

public class DownLoadServlet extends HttpServlet {

	/**
	 * The doGet method of the servlet. <br>
	 * 
	 * This method is called when a form has its tag value method equals to get.
	 * 
	 * @param request
	 *            the request send by the client to the server
	 * @param response
	 *            the response send by the server to the client
	 * @throws ServletException
	 *             if an error occurred
	 * @throws IOException
	 *             if an error occurred
	 */
	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		this.doPost(request, response);
	}

	/**
	 * The doPost method of the servlet. <br>
	 * 
	 * This method is called when a form has its tag value method equals to
	 * post.
	 * 
	 * @param request
	 *            the request send by the client to the server
	 * @param response
	 *            the response send by the server to the client
	 * @throws ServletException
	 *             if an error occurred
	 * @throws IOException
	 *             if an error occurred
	 */
	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// 得到要下载的文件名
		String fileName = request.getParameter("filename");
		//System.out.println(fileName);
		fileName = new String(fileName.getBytes("iso8859-1"), "UTF-8");
		// 上传的文件都是保存在/WEB-INF/upload目录下的子目录当中
		String fileSaveRootPath = this.getServletContext().getRealPath("/WEB-INF/upload");
		// 通过文件名找出文件的所在目录
		String path = findFileSavePathByFileName(fileName, fileSaveRootPath);
		// 得到要下载的文件
		File file = new File(path + "\\" + fileName);
		// 如果文件不存在
		if (!file.exists()) {
			request.setAttribute("message", "您要下载的资源已被删除!!");
			request.getRequestDispatcher("/message.jsp").forward(request,
					response);
			return;
		}
		// 处理文件名
		String realname = fileName.substring(fileName.indexOf("_") + 1);
		// 设置响应头,控制浏览器下载该文件
		response.setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode(realname, "UTF-8"));
		// 读取要下载的文件,保存到文件输入流
		FileInputStream in = new FileInputStream(path + "\\" + fileName);
		// 创建输出流
		OutputStream out = response.getOutputStream();
		// 创建缓冲区
		byte buffer[] = new byte[1024];
		int len = 0;
		// 循环将输入流中的内容读取到缓冲区当中
		while ((len = in.read(buffer)) > 0) {
			// 输出缓冲区的内容到浏览器,实现文件下载
			out.write(buffer, 0, len);
		}
		// 关闭文件输入流
		in.close();
		// 关闭输出流
		out.close();

	}

	public String findFileSavePathByFileName(String filename,
			String saveRootPath) {
		/*int hashcode = filename.hashCode();
		System.out.println(hashcode);
		int dir1 = hashcode & 0xf; // 0--15
		int dir2 = (hashcode & 0xf0) >> 4; // 0-15
		String dir = saveRootPath + "\\" + dir1 + "\\" + dir2; // upload\2\3
																// upload\3\5
		File file = new File(dir);
		if (!file.exists()) {
			// 创建目录
			file.mkdirs();
		}*/
		String filedate = FilenameUtils.MONTH_FORMAT.format(new Date());
		String dir = saveRootPath+filedate;
		return dir;
	}

}


 

message.jsp  :

 

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>message</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="description" content="This is my page">
	<script type="text/javascript" src="jquery.js"></script>
  </head>
  
  <body>
    <h1>${message}</h1>
    <a href="${pageContext.request.contextPath}/servlet/ListFileServlet">下载</a>
  </body>
</html>


 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值