专注收集记录技术开发学习笔记、技术难点、解决方案
网站信息搜索 >> 请输入关键词:
您当前的位置: 首页 > Web前端

javaweb文件上传的九大有关问题

发布时间:2010-05-20 14:01:29 文章来源:www.iduyao.cn 采编人员:星星草
javaweb文件上传的九大问题
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.SizeLimitExceededExcept

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-databoolean isMultipart = ServletFileUpload.isMultipartContent(request);if(!isMultipart){   pw.write("传输方式有错误!");   return;}ServletFileUpload upload = new ServletFileUpload(factory);upload.setFileSizeMax(4*1024*1024);//设置单个文件大小不能超过4Mupload.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/12File file = new File(path);if (!file.exists())file.mkdirs();return path;}

友情提示:
信息收集于互联网,如果您发现错误或造成侵权,请及时通知本站更正或删除,具体联系方式见页面底部联系我们,谢谢。

其他相似内容:

热门推荐: