一.maven依赖

  1. <dependency>
  2. <groupId>commons-fileupload</groupId>
  3. <artifactId>commons-fileupload</artifactId>
  4. <version>1.3.1</version>
  5. </dependency>
  6. <dependency>
  7. <groupId>commons-io</groupId>
  8. <artifactId>commons-io</artifactId>
  9. <version>2.4</version>
  10. </dependency>

二.DiskFileItemFactory类的使用

将请求消息实体中的每一个项目封装成单独的DiskFileItem (FileItem接口的实现) 对象的任务
由 org.apache.commons.fileupload.FileItemFactory 接口的默认实现 
org.apache.commons.fileupload.disk.DiskFileItemFactory 来完成。当上传的文件项目比较小时,直接保存在内存中(速度比较快),比较大时,以临时文件的形式,保存在磁盘临时文件夹(虽然速度慢些,但是内存资源是有限的)。

属性
1) public static final int DEFAULT_SIZE_THRESHOLD :将文件保存在内存还是磁盘临时文件夹的默认临界值,值为10240,即10kb。

2) private File repository:用于配置在创建文件项目时,当文件项目大于临界值时使用的临时文件夹,默认采用系统默认的临时文件路径,可以通过系统属性 java.io.tmpdir获取。如下代码:

System.getProperty("java.io.tmpdir");

3) private int sizeThreshold:用于保存将文件保存在内存还是磁盘临时文件夹的临界值

构造方法
1) public DiskFileItemFactory()

采用默认临界值和系统临时文件夹构造文件项工厂对象。

2) public DiskFileItemFactory(int sizeThreshold,File repository)

采用参数指定临界值和系统临时文件夹构造文件项工厂对象。

3) FileItem createItem() 
       根据DiskFileItemFactory相关配置将每一个请求消息实体项目创建成DiskFileItem 实例,并返回。该方法从来不需要我们亲自调用,FileUpload组件在解析请求时内部使用。

4) void setSizeThreshold(int sizeThreshold)
        Apache文件上传组件在解析上传数据中的每个字段内容时,需要临时保存解析出的数据,以便在后面进行数据的进一步处理(保存在磁盘特定位置或插入数据库)。因为Java虚拟机默认可以使用的内存空间是有限的,超出限制时将会抛出“java.lang.OutOfMemoryError”错误。如果上传的文件很大,例如800M的文件,在内存中将无法临时保存该文件内容,Apache文件上传组件转而采用临时文件来保存这些数据;但如果上传的文件很小,例如600个字节的文件,显然将其直接保存在内存中性能会更加好些。

setSizeThreshold方法用于设置是否将上传文件已临时文件的形式保存在磁盘的临界值(以字节为单位的int值),如果从没有调用该方法设置此临界值,将会采用系统默认值10KB。对应的getSizeThreshold() 方法用来获取此临界值。

5) void setRepository(File repository)
        setRepositoryPath方法用于设置当上传文件尺寸大于setSizeThreshold方法设置的临界值时,将文件以临时文件形式保存在磁盘上的存放目录。有一个对应的获得临时文件夹的 File getRespository() 方法。

注意:当从没有调用此方法设置临时文件存储目录时,默认采用系统默认的临时文件路径,可以通过系统属性 java.io.tmpdir 获取。如下代码:

System.getProperty("java.io.tmpdir");

Tomcat系统默认临时目录为“<tomcat安装目录>/temp/”。

 三.使用Commons-Fileupload包进行大文件上传注意事项

项目中使用

commons-fileupload-1.2.1.jar

进行大文件上传。

测试了一把,效果很不错。

总结如下:

  1. 必须设置好上传文件的最大阀值

    final long MAX_SIZE = 10 * 1024 * 1024 * 1024;// 设置上传文件最大为 10G

  2. 必须设置文件上传服务器上的临时目录

    // 文件上传参数配置
    // 创建一个新的文件上传句柄  
    DiskFileItemFactory factory = new DiskFileItemFactory();  
    // 设置内存缓冲区,超过后写入临时文件
    factory.setSizeThreshold(4096);  
    // 设置上传到服务器上文件的临时存放目录 -- 非常重要,防止存放到系统盘造成系统盘空间不足
    factory.setRepository(new File("F:\\uploadFileTemp"));
    ServletFileUpload upload = new ServletFileUpload(factory);  
    upload.setHeaderEncoding("utf-8"); 
     
    // 设置单个文件的最大上传值
    upload.setSizeMax(MAX_SIZE);  // 文件上传上限10G

  3. 上传成功后一定要删除临时目录的临时文件

    fileItem.delete(); // 请务必调用,在文件上传结束后,删除临时目录的文件...

  4. 最好记录下文件从开始上传到上传结束的时间点,这个对今后文件上传时间的分析很有用

另外,因为Struts2的上传功能也引入了该包,但是却做了拦截器限制文件的最大上传大小为2M,可以通过修改它的配置文件动态更改上传文件的大小;而且,Struts会在文件上传成功后,帮你删除掉临时文件。

我这里使用的是Spring MVC,需要在上传类中指定最大上传文件大小,(这玩意一般不动态设置,最大上传文件大小一般是系统的标准,是让使用者遵循滴),而且必须在上传成功后删除临时文件。

四.示例代码

1)JSP界面

  1. <%@ page language="java" contentType="text/html; charset=UTF-8"
  2. pageEncoding="UTF-8"%>
  3. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
  4. <html>
  5. <head>
  6. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  7. <title>Insert title here</title>
  8. </head>
  9. <body>
  10. <form action="UploadFile" method="post" enctype="multipart/form-data" multiple>
  11. <input type="file" name="myFile" size="10" >
  12. <input type="submit" value="上传文件">
  13. </form>
  14.  
  15. </body>
  16. </html>

2)servlet处理代码

  1. package com.my.web;
  2.  
  3. import java.io.File;
  4. import java.io.IOException;
  5. import java.util.Iterator;
  6. import java.util.List;
  7.  
  8. import javax.servlet.Servlet;
  9. import javax.servlet.ServletConfig;
  10. import javax.servlet.ServletException;
  11. import javax.servlet.annotation.WebInitParam;
  12. import javax.servlet.annotation.WebServlet;
  13. import javax.servlet.http.HttpServlet;
  14. import javax.servlet.http.HttpServletRequest;
  15. import javax.servlet.http.HttpServletResponse;
  16.  
  17. import org.apache.commons.fileupload.FileItem;
  18. import org.apache.commons.fileupload.FileUploadException;
  19. import org.apache.commons.fileupload.disk.DiskFileItemFactory;
  20. import org.apache.commons.fileupload.servlet.ServletFileUpload;
  21.  
  22. /**
  23. * Servlet implementation class UploadFile
  24. */
  25. @WebServlet(name = "UploadFile", urlPatterns = { "/UploadFile" }, initParams = {
  26. @WebInitParam(name = "filepath", value = "D:/Tools/sandbox/data/") })
  27. public class UploadFile extends HttpServlet {
  28. private static final long serialVersionUID = 1L;
  29. private int maxFileSize = 50 * 1024;
  30. private int maxMemSize = 4 * 1024;
  31. private boolean isMultipart;
  32. private String filePath;
  33. private File file;
  34.  
  35. /**
  36. * @see HttpServlet#HttpServlet()
  37. */
  38. public UploadFile() {
  39. super();
  40. // TODO Auto-generated constructor stub
  41. }
  42.  
  43. /**
  44. * @see Servlet#init(ServletConfig)
  45. */
  46. public void init(ServletConfig config) throws ServletException {
  47. // TODO Auto-generated method stub
  48. filePath = config.getInitParameter("filepath").toString();
  49. System.out.println(filePath);
  50. }
  51.  
  52. /**
  53. * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
  54. * response)
  55. */
  56. protected void doGet(HttpServletRequest request, HttpServletResponse response)
  57. throws ServletException, IOException {
  58. // TODO Auto-generated method stub
  59.  
  60. // 用于判断是普通表单,还是带文件上传的表单
  61. isMultipart = ServletFileUpload.isMultipartContent(request);
  62.  
  63. response.setContentType("text/html; charset=UTF-8");
  64. DiskFileItemFactory factory = new DiskFileItemFactory();
  65. factory.setSizeThreshold(maxMemSize);
  66. // Location to save data that is larger than maxMemSize.
  67. factory.setRepository(new File("D:\\Tools\\sandbox\\temp"));
  68.  
  69. // 创建一个新的文件上传处理程序
  70. ServletFileUpload upload = new ServletFileUpload(factory);
  71. upload.setHeaderEncoding("UTF-8");
  72. //允许上传的文件大小的最大值
  73. upload.setSizeMax(maxFileSize);
  74.  
  75. try {
  76. // 解析请求,获取文件项
  77. List<FileItem> fileItems = upload.parseRequest(request);
  78. // 处理上传的文件项
  79. Iterator i = fileItems.iterator();
  80. while ( i.hasNext () )
  81. {
  82. FileItem fi = (FileItem)i.next();
  83. if ( !fi.isFormField () )
  84. {
  85. // 获取上传文件的参数
  86. String fieldName = fi.getFieldName();
  87. String fileName = fi.getName();
  88. String contentType = fi.getContentType();
  89. boolean isInMemory = fi.isInMemory();
  90. long sizeInBytes = fi.getSize();
  91. // 写入文件
  92. if( fileName.lastIndexOf("\\") >= 0 ){
  93. file = new File( filePath +
  94. fileName.substring( fileName.lastIndexOf("\\"))) ;
  95. }else{
  96. file = new File( filePath +
  97. fileName.substring(fileName.lastIndexOf("\\")+1)) ;
  98. }
  99. fi.write( file ) ;
  100. }
  101. }
  102.  
  103. } catch (FileUploadException e) {
  104. // TODO Auto-generated catch block
  105. e.printStackTrace();
  106. } catch (Exception e) {
  107. // TODO Auto-generated catch block
  108. e.printStackTrace();
  109. }
  110. response.getWriter().append("Served at: ").append(String.valueOf(isMultipart));
  111. }
  112.  
  113. /**
  114. * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
  115. * response)
  116. */
  117. protected void doPost(HttpServletRequest request, HttpServletResponse response)
  118. throws ServletException, IOException {
  119. // TODO Auto-generated method stub
  120. doGet(request, response);
  121. }
  122.  
  123. }

或者

  1. package com.my.web;
  2.  
  3. import java.io.File;
  4. import java.io.IOException;
  5. import java.util.Iterator;
  6. import java.util.List;
  7.  
  8. import javax.servlet.Servlet;
  9. import javax.servlet.ServletConfig;
  10. import javax.servlet.ServletException;
  11. import javax.servlet.annotation.WebInitParam;
  12. import javax.servlet.annotation.WebServlet;
  13. import javax.servlet.http.HttpServlet;
  14. import javax.servlet.http.HttpServletRequest;
  15. import javax.servlet.http.HttpServletResponse;
  16.  
  17. import org.apache.commons.fileupload.FileItem;
  18. import org.apache.commons.fileupload.FileUploadException;
  19. import org.apache.commons.fileupload.disk.DiskFileItemFactory;
  20. import org.apache.commons.fileupload.servlet.ServletFileUpload;
  21.  
  22. /**
  23. * Servlet implementation class UploadFile
  24. */
  25. @WebServlet(name = "UploadFile2", urlPatterns = { "/UploadFile2" }, initParams = {
  26. @WebInitParam(name = "filepath", value = "D:/Tools/sandbox/data/") })
  27. public class UploadFile2 extends HttpServlet {
  28. private static final long serialVersionUID = 1L;
  29. private int maxFileSize = 50 * 1024;
  30. private int maxMemSize = 4 * 1024;
  31. private boolean isMultipart;
  32. private String filePath;
  33. private File file;
  34.  
  35. /**
  36. * @see HttpServlet#HttpServlet()
  37. */
  38. public UploadFile2() {
  39. super();
  40. // TODO Auto-generated constructor stub
  41. }
  42.  
  43. /**
  44. * @see Servlet#init(ServletConfig)
  45. */
  46. public void init(ServletConfig config) throws ServletException {
  47. // TODO Auto-generated method stub
  48. filePath = config.getInitParameter("filepath").toString();
  49. System.out.println(filePath);
  50. }
  51.  
  52. /**
  53. * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
  54. * response)
  55. */
  56. protected void doGet(HttpServletRequest request, HttpServletResponse response)
  57. throws ServletException, IOException {
  58. // TODO Auto-generated method stub
  59.  
  60. // 用于判断是普通表单,还是带文件上传的表单
  61. isMultipart = ServletFileUpload.isMultipartContent(request);
  62.  
  63. response.setContentType("text/html; charset=UTF-8");
  64. DiskFileItemFactory factory = new DiskFileItemFactory();
  65. factory.setSizeThreshold(maxMemSize);
  66. // Location to save data that is larger than maxMemSize.
  67. factory.setRepository(new File("D:\\Tools\\sandbox\\temp"));
  68.  
  69. // 创建一个新的文件上传处理程序
  70. ServletFileUpload upload = new ServletFileUpload(factory);
  71. upload.setHeaderEncoding("UTF-8");
  72. //允许上传的文件大小的最大值
  73. upload.setSizeMax(maxFileSize);
  74.  
  75. try {
  76. // 解析请求,获取文件项
  77. List<FileItem> fileItems = upload.parseRequest(request);
  78. for (FileItem item : fileItems) {
  79. if(item.isFormField()){
  80. String name = item.getFieldName();
  81. //解决普通输入项的数据的中文乱码问题
  82. String value = item.getString("UTF-8");
  83. //value = new String(value.getBytes("iso8859-1"),"UTF-8");
  84. System.out.println(name + "=" + value);
  85. }else{//如果fileitem中封装的是上传文件
  86. //得到上传的文件名称,
  87. String filename = item.getName();
  88. System.out.println(filename);
  89. if(filename==null || filename.trim().equals("")){
  90. continue;
  91. }
  92. //注意:不同的浏览器提交的文件名是不一样的,有些浏览器提交上来的文件名是带有路径的,如: c:\a\b\1.txt,而有些只是单纯的文件名,如:1.txt
  93. //处理获取到的上传文件的文件名的路径部分,只保留文件名部分
  94. filename = filename.substring(filename.lastIndexOf("\\")+1);
  95. //得到上传文件的扩展名
  96. String fileExtName = filename.substring(filename.lastIndexOf(".")+1);
  97. filename = filename.substring(0,filename.lastIndexOf("."));
  98. //如果需要限制上传的文件类型,那么可以通过文件的扩展名来判断上传的文件类型是否合法
  99. System.out.println("上传的文件的扩展名是:"+fileExtName);
  100. //保存文件
  101. file = new File( filePath + filename +"." + fileExtName);
  102. item.write(file);
  103. }
  104. }
  105.  
  106. } catch (FileUploadException e) {
  107. // TODO Auto-generated catch block
  108. e.printStackTrace();
  109. } catch (Exception e) {
  110. // TODO Auto-generated catch block
  111. e.printStackTrace();
  112. }
  113. request.getRequestDispatcher("/uploadFile.jsp").forward(request, response);
  114. }
  115.  
  116. /**
  117. * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
  118. * response)
  119. */
  120. protected void doPost(HttpServletRequest request, HttpServletResponse response)
  121. throws ServletException, IOException {
  122. // TODO Auto-generated method stub
  123. doGet(request, response);
  124. }
  125.  
  126. }

5.servlet 上传文件的更多相关文章

  1. 使用Servlet上传文件

    使用浏览器向服务器上传文件其本质是打开了一个长连接并通过TCP方式传输数据.而需要的动作是客户端在表单中使用file域,并指定该file域的name值,然后在form中设定enctype的值为mult ...

  2. Servlet上传文件

    Servlet上传文件 1.准备工作 (1)利用FileUpload组件上传文件,须要到apache上下载commons-fileupload-1.3.1.jar 下载地址:http://common ...

  3. 原生Servlet 上传文件

    依赖jar <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons ...

  4. java servlet上传文件并把文件内容显示在网页中

    servlet3.0(JDK1.6)自带的API即可实现本地文件的上传,Servlet3.0新增了Part接口,HttpServletRequest的getPart()方法取得Part实现对象.下面我 ...

  5. servlet上传文件报错(三)

    1.具体报错如下 null null Exception in thread "http-apr-8686-exec-5" java.lang.OutOfMemoryError: ...

  6. JSP && Servlet | 上传文件

    在WebContent下新建index.jsp 要点: 1.  表单 method 属性应该设置为 POST 方法,不能使用 GET 方法. 2.  表单 enctype 属性应该设置为 multip ...

  7. J2EE:Servlet上传文件到服务器,并相应显示

    Servlet 可以与HTML一起使用来允许用户上传文件到服务器 编辑上传文件的页面upload.html 注意事项:上传方式使用POST不能使用GET(GET不能上传文件) 表单 enctype 属 ...

  8. servlet上传文件报错(二)

    1.具体报错如下: java.io.FileNotFoundException: D:\MyEclipse\workspace\FileUpload\WebRoot\upload (拒绝访问.) at ...

  9. JAVA servlet 上传文件(commons-fileupload, commons-io)

    <1>获取二进制文件流并输出 InputStream inputStream = request.getInputStream(); BufferedReader reader = new ...

随机推荐

  1. Python -- Gui编程 -- Tkinter的使用 -- 菜单与画布

    1.菜单 tkMenu.py import tkinter root = tkinter.Tk() menu = tkinter.Menu(root) submenu = tkinter.Menu(m ...

  2. Spring+Druid+SpringMVC的搭建(附Demo)

    最近公司事情比较少,便想利用这段空闲时间做一个自己的博客. 前端界面已经搞好,感谢杨姐的模板,自己稍微把模板没有的模块给补全了. 今天便开始自己的SSM框架搭建,数据库链接是采用数据库连接池.先上个项 ...

  3. 深入理解Java虚拟机:垃圾收集器与内存分配策略

    目录 3.2 对象已死吗 判断一个对象是否可被回收 引用类型 finalize() 回收方法区 3.3. 垃圾收集算法 1.Mark-Sweep(标记-清除)算法 2.Copying(复制)算法 3. ...

  4. MySQL中You can't specify target table for update in FROM clause异常

    mysql中You can't specify target table <tbl> for update in FROM clause错误的意思是说,不能先select出同一表中的某些值 ...

  5. spring cloud连载第三篇补充之Zuul

    由于Zuul的内容较多所以单独列出一篇来讲.全是干货,如果学到东西的,动动小手给点个推荐^_^  谢谢! 1. Router and Filter: Zuul(路由和过滤:Zuul) 路由是微服务架构 ...

  6. Docker容器打包成镜像 - OpenDaylight官方 SDN Hub Tutorial VM 的docker镜像

    由于工作需要,在看OpenDaylight (一个SDN的开源控制器) 官方Tutorial有一个比较基础且介绍比较详细的文档(http://sdnhub.org/tutorials/opendayl ...

  7. PHP数组基本的操作方法

    1.数组操作的基本函数 数组的键和值: array_values($arr);获得数组的值 array_keys($arr);获得数组的键名 array_flip($arr);数组中的值与键名互换(如 ...

  8. emberjs 按年月分组

    一个集合,里面有年和月的属性,按照年和月进行分组显示数据 + item.TopicMonth }).map(function (value, key) { return { time: { year: ...

  9. 转载:@Html.ValidationSummary(true)

    ASP.NET MVC3 Model验证总结 @Html.ValidationSummary(true)   http://www.wyjexplorer.cn/Post/2012/8/3/model ...

  10. 测试使用highlight.js的代码效果

    ---恢复内容开始--- C#代码 private void NextDateUpdate(DateTime dtt) { dtt.AddDays(); Response.Write("dt ...