javaweb文件上传的九大问题

一、文件上传中要注意的9个问题


1、如何保证服务器的安全
把保存上传文件的目录放到WEB-INF目录中。
  2、中文乱码问题
        2.1普通字段的中文请求参数
String value = FileItem.getString("UTF-8");
2.2上传的文件名是中文
解决办法:request.setCharacterEncoding("UTF-8");
  3、重名文件被覆盖的问题
System.currentMillions()+"_"+a.txt(乐观)
        UUID+"_"+a.txt:保证文件名唯一
  4、分目录存储上传的文件

方式一:当前日期建立一个文件夹,当前上传的文件都放到此文件夹中。

                               例如:生成一个2014-10-6的文件夹                     

                Date date = new Date();
               DateFormat df = DateFormat.getDateInstance(DateFormat.MEDIUM);
		String s = df.format(date);
		String path = storePath+"\\"+s;
		File file = new File(path);
		if(!file.exists())
		{
			file.mkdirs();//创建多级目录,mkdir只创建一级目录
		}
		return path;//文件夹的地址

方式二:利用文件名的hash码打散目录来存储。
int hashCode = fileName.hashCode();

1001 1010 1101 0010 1101 1100 1101 1010
hashCode&0xf   0000 0000 0000 0000 0000 0000 0000 1111 &
---------------------------------------------
0000 0000 0000 0000 0000 0000 0000 1010   取hashCode的后4位
0000~1111:整数0~15共16个

1001 1010 1101 0010 1101 1100 1101 1010
(hashCode&0xf0) 0000 0000 0000 0000 0000 0000 1111 0000  &
--------------------------------------------
0000 0000 0000 0000 0000 0000 1101 0000  >>4
--------------------------------------------
0000 0000 0000 0000 0000 0000 0000 1101
     0000~1111:整数0~15共16个

5、限制用户上传的文件类型
通过判断文件的扩展名来限制是不可取的。

通过判断其Mime类型才靠谱。FileItem.getContentType();


    6、如何限制用户上传文件的大小
6.1单个文件大小限制。超出了大小友好提示
抓异常进行提示:org.apache.commons.fileupload.FileUploadBase.FileSizeLimitExceededException
6.2总文件大小限制。超出了大小友好提示

抓异常进行提示:org.apache.commons.fileupload.FileUploadBase.SizeLimitExceededException


    7、临时文件的问题
commons-fileupload组件不会删除超出缓存的临时文件。

FileItem.delete()方法删除临时文件。但一定要在关闭流之后。
    8、多个文件上传时,没有上传内容的问题          
if(fileName==null||"".equals(fileName.trim())){
			continue;
		}

    9、上传进度检测
给ServletFileUpload注册一个进度监听器即可,把上传进度传递给页面去显示
//pBytesRead:当前以读取到的字节数
//pContentLength:文件的长度
//pItems:第几项
public void update(long pBytesRead, long pContentLength,
				int pItems) {
			System.out.println("已读取:"+pBytesRead+",文件大小:"+pContentLength+",第几项:"+pItems);
		}


完整实例 :

表单:

<%@ 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>My JSP '1.jsp' starting 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}/servlet/UploadServlet3" method="post" enctype="multipart/form-data">
   用户名<input type="text" name="username"/> <br/>
   <input type="file" name="f1"/><br/>
   <input type="file" name="f2"/><br/>
   <input type="submit" value="保存"/>
 </form>
  </body>
</html>

UploadServlet3

package com.mair.upload;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.text.DateFormat;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import java.util.logging.SimpleFormatter;

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

public class UploadServlet3 extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		
		//设置编码
		request.setCharacterEncoding("UTF-8");
		response.setContentType("text/html;charset=UTF-8");
		PrintWriter pw = response.getWriter();
		try {
			//设置系统环境
			DiskFileItemFactory factory = new DiskFileItemFactory();
			//文件存储的路径
			String storePath = getServletContext().getRealPath("/WEB-INF/files");
			//判断传输方式  form  enctype=multipart/form-data
			boolean isMultipart = ServletFileUpload.isMultipartContent(request);
			if(!isMultipart)
			{
			   	pw.write("传输方式有错误!");
			   	return;
			}
			ServletFileUpload upload = new ServletFileUpload(factory);
			upload.setFileSizeMax(4*1024*1024);//设置单个文件大小不能超过4M
			upload.setSizeMax(4*1024*1024);//设置总文件上传大小不能超过6M
			//监听上传进度
			upload.setProgressListener(new ProgressListener() {

				//pBytesRead:当前以读取到的字节数
 				//pContentLength:文件的长度
 				//pItems:第几项
				public void update(long pBytesRead, long pContentLength,
						int pItems) {
					System.out.println("已读去文件字节 :"+pBytesRead+" 文件总长度:"+pContentLength+"   第"+pItems+"项");
					
				}
			});
			//解析
			List<FileItem> items = upload.parseRequest(request);
			for(FileItem item: items)
			{
				if(item.isFormField())//普通字段,表单提交过来的
				{
					String name = item.getFieldName();
					String value = item.getString("UTF-8");
					System.out.println(name+"=="+value);
				}else
				{
//					String mimeType = item.getContentType(); 获取上传文件类型
//					if(mimeType.startsWith("image")){
					InputStream in =item.getInputStream();
					String fileName = item.getName(); 
					if(fileName==null || "".equals(fileName.trim()))
					{
						continue;
					}
					fileName = fileName.substring(fileName.lastIndexOf("\\")+1);
					fileName = UUID.randomUUID()+"_"+fileName;
					
					//按日期来建文件夹
					String newStorePath = makeStorePath(storePath);
					String storeFile = newStorePath+"\\"+fileName;
					OutputStream out = new FileOutputStream(storeFile);
					byte[] b = new byte[1024];
					int len = -1;
					while((len = in.read(b))!=-1)
					{
				         out.write(b,0,len);		
					}
					in.close();
					out.close();
					item.delete();//删除临时文件
				}
			  }
//			}
		}catch(org.apache.commons.fileupload.FileUploadBase.FileSizeLimitExceededException e){ 
		      //单个文件超出异常
			pw.write("单个文件不能超过4M");
		}catch(org.apache.commons.fileupload.FileUploadBase.SizeLimitExceededException e){
			//总文件超出异常
			pw.write("总文件不能超过6M");
			
		}catch (FileUploadException e) {
			e.printStackTrace();
		}
		
		

	}
       //用日期生成的目录,如果想用hashcode,后面
	private String makeStorePath(String storePath) {
		
		Date date = new Date();
		DateFormat df = DateFormat.getDateInstance(DateFormat.MEDIUM);
		String s = df.format(date);
		String path = storePath+"\\"+s;
		File file = new File(path);
		if(!file.exists())
		{
			file.mkdirs();//创建多级目录,mkdir只创建一级目录
		}
		return path;
		 
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
        doGet(request, response);
	}

}


用hashcode生成目录:只需要改写一下makeStorePath(String storePath, String fileName)函数

	private String makeStorePath(String storePath, String fileName) {
		int hashCode = fileName.hashCode();
		int dir1 = hashCode & 0xf;// 0000~1111:整数0~15共16个
		int dir2 = (hashCode & 0xf0) >> 4;// 0000~1111:整数0~15共16个

		String path = storePath + "\\" + dir1 + "\\" + dir2; // WEB-INF/files/1/12
		File file = new File(path);
		if (!file.exists())
			file.mkdirs();

		return path;
	}



  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值