java web上传、下载文件源码以及应该注意的问题

      在使用jsp上传文件给后台时需要注意的几点:

        upload.setHeaderEncoding("UTF-8");//解决上传文件名的中文乱码
  //下面这句代码并不能解决form提交中文数据乱码的问题(表单为文件上传的时候)
  // request.setCharacterEncoding
   // 所以只能手工转换
   String value=item.getString();

   value=new String(value.getBytes("ISO8859-1"),"UTF-8");
  //也可以这样写
  String value=item.getString("UTF-8");


2.为了保证服务器安全,上传文件应该放在外界无法直接访问的目录


3.为了防止文件名重复,需要为每次上传的文件生成一个唯一的文件名


4.为了防止同一个目录下文件过多导致访问变慢的问题,需要将上传文件尽量打散(多个文件夹)
  这里使用的是hash算法。


5.要限制上传文件最大值
  
6.想确保临时文件被删除,需要在上传完成后(流已关闭),调用item.delete();


7.限制文件的类型,收到上传文件名时,通过文件后缀名判断


8.监听文件上传进度


上传界面代码:

<%@ 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>Insert title here</title>
</head>
<body>
 <form action="${pageContext.request.contextPath }/UploadServlet1" enctype="multipart/form-data" method="post">
   上传用户:<input type="text" name="username"><br>
   上传文件1: <input type="file" name="file1">${message }<br>
   上传文件2: <input type="file" name="file2">${message }<br>
   <input type="submit" value="提交">
   </form>
   
</body>
</html>


servlet代码:

package com.wz.servlet;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Set;
import java.util.UUID;

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 org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadBase;
import org.apache.commons.fileupload.ProgressListener;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.tomcat.util.http.fileupload.RequestContext;

/**
 * Servlet implementation class UploadServlet1
 */
@WebServlet("/UploadServlet1")
public class UploadServlet1 extends HttpServlet {
	private static final long serialVersionUID = 1L;

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

		request.getParameter("username");

		// 得到上传目录
		String savePath = this.getServletContext().getRealPath("/WEB-INF/upload");
		try {
			DiskFileItemFactory factory = new DiskFileItemFactory();
			//如果文件大于缓冲区大小(默认为10k),则使用临时文件保存数据,下面是设置临时文件的目录
			factory.setRepository(new File(this.getServletContext().getRealPath("/WEB-INF/temp")));
			ServletFileUpload upload = new ServletFileUpload(factory);
			//监听文件上传进度
			upload.setProgressListener(new ProgressListener() {
				//第一个参数是已经读取多少,第二个是当前文件大小,第三个是当前是第几个文件
				@Override
				public void update(long arg0, long arg1, int arg2) {
					// 你的操作。。。。
					
				}
			});
			
			if (!upload.isMultipartContent(request)) {
				// 按照传统方式获取数据
				return;
			}

			upload.setFileSizeMax(1024*1024);// 设置上传文件不大于1M
			upload.setSizeMax(1024*1024*10);//上传总量 
			upload.setHeaderEncoding("UTF-8");
			List<FileItem> list = upload.parseRequest(request);
			for (FileItem item : list) {
				if (item.isFormField()) {
					// fileItem中封装的是普通输入项的数据
					String name = item.getFieldName();
					String value = item.getString();
					value = new String(value.getBytes("ISO8859-1"), "UTF-8");
					System.out.println(name + "=" + value);
				} else {
					if(item.getName()==null||item.getName().trim().equals("")){
						continue;
					}
					// fileItem中封装的是上传文件
					String filename = item.getName();
					filename = filename.substring(filename.lastIndexOf("\\") + 1);

					InputStream in = item.getInputStream();
					// 生成唯一文件名
					String savaFileName = makeName(filename);
					// 根据唯一文件名的hash码生成子目录
					String savePaths = makePath(savaFileName, savePath);
					FileOutputStream out = new FileOutputStream(savePaths + "\\" + savaFileName);
					byte buffer[] = new byte[1024];
					int len = 0;
					while ((len = in.read(buffer)) > 0) {
						out.write(buffer, 0, len);
					}
					in.close();
					out.close();
					//删除临时文件操作,可以确保临时文件删除,此操作必须在流关闭之后
					item.delete();
				}
			}
		} 
		catch(FileUploadBase.FileSizeLimitExceededException e){
	       request.setAttribute("message", "上传文件过大!");
	       request.getRequestDispatcher("/upload.jsp").forward(request, response);
	       return;
		}
		catch (Exception e) {
			e.printStackTrace();
		}
		// response.getWriter().write("ewqeqweqweqw");
	}

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

	public String makeName(String filename) {
		return UUID.randomUUID().toString() + "_" + filename;
	}

	public String makePath(String filename, String savePath) {
		int hashcode = filename.hashCode();
		int dir1 = hashcode & 0xf;
		int dir2 = hashcode & 0xf0;
		String dir = savePath + "\\" + dir1 + "\\" + dir2;
		File file = new File(dir);
		if (!file.exists()) {
			file.mkdirs();// 注意此处是mkdirs而不是mkdir,因为需要生成二级目录
		}
		return dir;
	}

}



显示文件jsp代码:
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!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>Insert title here</title>
</head>
<body>
   <c:forEach var="me" items="${map }">
   <%-- 在URL参数中如果出现非ASCII码字符,需要先进行编码 --%>
   <c:url value="/DownloadServlet" var="downurl">
   <c:param name="filename" value="${me.key }"></c:param>
   </c:url>
   ${me.value }<a href="${downurl }">下载</a><br>
   </c:forEach>
</body>
</html>

servlet:

package com.wz.servlet;

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

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

/**
 * Servlet implementation class ListFileServlet
 */
@WebServlet("/ListFileServlet")
public class ListFileServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            response.setCharacterEncoding("UTF-8");
		    String filepath=  this.getServletContext().getRealPath("/WEB-INF/upload");
            Map map=new HashMap<>();
            listfile(new File(filepath),map);
            request.setAttribute("map", map);
            request.getRequestDispatcher("/WEB-INF/listfile.jsp").forward(request, response);
	}
	//递归遍历文件
	public void listfile(File file,Map map){
		if(!file.isFile()){
		File files[]=file.listFiles();
		for(File f:files){
			listfile(f,map);
		}
		}else{
			String realname= file.getName().substring(file.getName().indexOf("_")+1);
			map.put(file.getName(), realname);
		}
	}

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

}



下载servlet:
package com.wz.servlet;

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.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class DownloadServlet
 */
@WebServlet("/DownloadServlet")
public class DownloadServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		
		String filename = request.getParameter("filename");
		// 防止乱码
		request.setCharacterEncoding("UTF-8");
		String path = makePath(filename,this.getServletContext().getRealPath("/WEB-INF/upload"));
		File file= new File(path+"\\"+filename);
         if(file.exists()){
        	 //通知文件以下载形式访问文件
 			String realname= filename.substring(file.getName().indexOf("_")+1);
        	response.setHeader("content-type", "zip");
 			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();
         }else{
        	 System.out.println("资源已删除");
         }
	}

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

	public String makePath(String filename, String savePath) {
		int hashcode = filename.hashCode();
		int dir1 = hashcode & 0xf;
		int dir2 = hashcode & 0xf0;
		String dir = savePath + "\\" + dir1 + "\\" + dir2;
		File file = new File(dir);
//		if (!file.exists()) {
//			file.mkdirs();// 注意此处是mkdirs而不是mkdir,因为需要生成二级目录
//		}
		return dir;

	}

}






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值