一.maven依赖

<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</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界面

<%@ 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="UploadFile" method="post" enctype="multipart/form-data" multiple>
<input type="file" name="myFile" size="10" >
<input type="submit" value="上传文件">
</form> </body>
</html>

2)servlet处理代码

package com.my.web;

import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import java.util.List; import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebInitParam;
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.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload; /**
* Servlet implementation class UploadFile
*/
@WebServlet(name = "UploadFile", urlPatterns = { "/UploadFile" }, initParams = {
@WebInitParam(name = "filepath", value = "D:/Tools/sandbox/data/") })
public class UploadFile extends HttpServlet {
private static final long serialVersionUID = 1L;
private int maxFileSize = 50 * 1024;
private int maxMemSize = 4 * 1024;
private boolean isMultipart;
private String filePath;
private File file; /**
* @see HttpServlet#HttpServlet()
*/
public UploadFile() {
super();
// TODO Auto-generated constructor stub
} /**
* @see Servlet#init(ServletConfig)
*/
public void init(ServletConfig config) throws ServletException {
// TODO Auto-generated method stub
filePath = config.getInitParameter("filepath").toString();
System.out.println(filePath);
} /**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
* response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// TODO Auto-generated method stub // 用于判断是普通表单,还是带文件上传的表单
isMultipart = ServletFileUpload.isMultipartContent(request); response.setContentType("text/html; charset=UTF-8");
DiskFileItemFactory factory = new DiskFileItemFactory();
factory.setSizeThreshold(maxMemSize);
// Location to save data that is larger than maxMemSize.
factory.setRepository(new File("D:\\Tools\\sandbox\\temp")); // 创建一个新的文件上传处理程序
ServletFileUpload upload = new ServletFileUpload(factory);
upload.setHeaderEncoding("UTF-8");
//允许上传的文件大小的最大值
upload.setSizeMax(maxFileSize); try {
// 解析请求,获取文件项
List<FileItem> fileItems = upload.parseRequest(request);
// 处理上传的文件项
Iterator i = fileItems.iterator();
while ( i.hasNext () )
{
FileItem fi = (FileItem)i.next();
if ( !fi.isFormField () )
{
// 获取上传文件的参数
String fieldName = fi.getFieldName();
String fileName = fi.getName();
String contentType = fi.getContentType();
boolean isInMemory = fi.isInMemory();
long sizeInBytes = fi.getSize();
// 写入文件
if( fileName.lastIndexOf("\\") >= 0 ){
file = new File( filePath +
fileName.substring( fileName.lastIndexOf("\\"))) ;
}else{
file = new File( filePath +
fileName.substring(fileName.lastIndexOf("\\")+1)) ;
}
fi.write( file ) ;
}
} } catch (FileUploadException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
response.getWriter().append("Served at: ").append(String.valueOf(isMultipart));
} /**
* @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);
} }

或者

package com.my.web;

import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import java.util.List; import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebInitParam;
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.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload; /**
* Servlet implementation class UploadFile
*/
@WebServlet(name = "UploadFile2", urlPatterns = { "/UploadFile2" }, initParams = {
@WebInitParam(name = "filepath", value = "D:/Tools/sandbox/data/") })
public class UploadFile2 extends HttpServlet {
private static final long serialVersionUID = 1L;
private int maxFileSize = 50 * 1024;
private int maxMemSize = 4 * 1024;
private boolean isMultipart;
private String filePath;
private File file; /**
* @see HttpServlet#HttpServlet()
*/
public UploadFile2() {
super();
// TODO Auto-generated constructor stub
} /**
* @see Servlet#init(ServletConfig)
*/
public void init(ServletConfig config) throws ServletException {
// TODO Auto-generated method stub
filePath = config.getInitParameter("filepath").toString();
System.out.println(filePath);
} /**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
* response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// TODO Auto-generated method stub // 用于判断是普通表单,还是带文件上传的表单
isMultipart = ServletFileUpload.isMultipartContent(request); response.setContentType("text/html; charset=UTF-8");
DiskFileItemFactory factory = new DiskFileItemFactory();
factory.setSizeThreshold(maxMemSize);
// Location to save data that is larger than maxMemSize.
factory.setRepository(new File("D:\\Tools\\sandbox\\temp")); // 创建一个新的文件上传处理程序
ServletFileUpload upload = new ServletFileUpload(factory);
upload.setHeaderEncoding("UTF-8");
//允许上传的文件大小的最大值
upload.setSizeMax(maxFileSize); try {
// 解析请求,获取文件项
List<FileItem> fileItems = upload.parseRequest(request);
for (FileItem item : fileItems) {
if(item.isFormField()){
String name = item.getFieldName();
//解决普通输入项的数据的中文乱码问题
String value = item.getString("UTF-8");
//value = new String(value.getBytes("iso8859-1"),"UTF-8");
System.out.println(name + "=" + value);
}else{//如果fileitem中封装的是上传文件
//得到上传的文件名称,
String filename = item.getName();
System.out.println(filename);
if(filename==null || filename.trim().equals("")){
continue;
}
//注意:不同的浏览器提交的文件名是不一样的,有些浏览器提交上来的文件名是带有路径的,如: c:\a\b\1.txt,而有些只是单纯的文件名,如:1.txt
//处理获取到的上传文件的文件名的路径部分,只保留文件名部分
filename = filename.substring(filename.lastIndexOf("\\")+1);
//得到上传文件的扩展名
String fileExtName = filename.substring(filename.lastIndexOf(".")+1);
filename = filename.substring(0,filename.lastIndexOf("."));
//如果需要限制上传的文件类型,那么可以通过文件的扩展名来判断上传的文件类型是否合法
System.out.println("上传的文件的扩展名是:"+fileExtName);
//保存文件
file = new File( filePath + filename +"." + fileExtName);
item.write(file);
}
} } catch (FileUploadException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
request.getRequestDispatcher("/uploadFile.jsp").forward(request, response);
} /**
* @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);
} }

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. PHP CURL 抓取失败 自己调试

    蛋疼的一下午,物理机win7旗舰版+APACHE2 ,CURL抓取一直成功. 虚拟机ubuntu+apache2一直抓取失败. 晚上,问个仁兄才知道,CURL可以调试: 参考这位兄台: 地址 curl ...

  2. win7,8走网络打印机出现删除设备和打印机门未关闭的解决方法

    不多说,直接上干货! 用学校的内网连接, 即可. 右键,查看设备网页. 出现下面的情况: 多学学. 欢迎大家,加入我的微信公众号:大数据躺过的坑        人工智能躺过的坑       同时,大家 ...

  3. Oracle中的层次查询详解

    1 语法格式 select [level], column, expr... from table [where condition] start with condition connect by ...

  4. springboot-14-自定义properties文件值注入javaBean中

    被这个问题困扰了好几天.... 在spring中, 从资源文件向bean中注入值非常简单, 只需要properties文件被spring加载, 然后在被spring管理的类写响应的属性, 然后 @Va ...

  5. centos6.5 + 7 静态ip配置

    2017/09/19日更, centos6.5 可用 DEVICE=eth0 TYPE=Ethernet ONBOOT=yes NM_CONTROLLED=yes BOOTPROTO=static D ...

  6. 面试:C/C++常见库函数实现

    1. void *mymemcpy(void *dest, const void* src, size_t n): 内存拷贝函数,memcpy函数的功能是从源src所指的内存地址的起始位置开始拷贝n个 ...

  7. vue2.x中请求之前数据显示以及vuex缓存的问题

    在项目中遇到两个问题,简单的做个笔记来记录自己解决的问题,可能不是很好的处理办法,欢迎提出,自己还在不断优化中... 第一个是vue在加载页面的时候,会先加载静态资源,这个时候数据还没有请求回来,用户 ...

  8. 3.C#基础篇-->堆和栈

    一.前言 堆与栈对于理解.NET中的内存管理.垃圾回收.错误和异常.调试与日志有很大的帮助.垃圾回收的机制使程序员从复杂的内存管理中解脱出来,虽然绝大多数的C#程序并不需要程序员手动管理内存,但这并不 ...

  9. saas模式

    SaaS是Software-as-a-service(软件即服务).SaaS提供商为企业搭建信息化所需要的所有网络基础设施及软件.硬件运作平台,并负责所有前期的实施.后期的维护等一系列服务,企业无需购 ...

  10. webAPP 图片上传

    关于webAPP 手机上传 用的vue.js 首先是js代码 调用手机app 的 相册或者自己拍照 upload: function(index) { //上传 this.index = index ...