使用commons-fileUpload组件上传文件
在近期的一个项目中有用到commons-fileUpload组件进行实现文件上传的功能(由于没用到框架),在使用的过程中有遇到一些问题,经过自己的琢磨也算顺利地将其解决了,在这里做个记录。
一、commons-fileUpload文件上传组件简介
commons-fileUpload上传组件是Apache的一个开源项目,可以到http://commons.apache.org/proper/commons-fileupload/下载最新版本(该组件需要commons-io包的支持)。该组件使用方便,同样可以实现一个或多个文件的上传,也可实现限制上传文件大小等功能。
在文件上传中,文件上传请求由有序的表单项列表组成,fileUpload能够解析上传请求,然后向应用提供一个单独的文件表单项的列表。每个这样的表单项都实现了FileItem接口,并包含例如文件名等属性。
二、使用要求
1、使用commons-fileUpload组件上传文件时,需要将form表单的enctype属性设置为multipart/form-data;同时还需要设置上传文件在内存中的大小,多余的部分存储在磁盘中。
2、将相应的commons-fileUpload包和commons-io包拷贝放入到你的web工程WEN-INF/lib目录下并Add to Build Path。
三、使用步骤
1、首先,创建磁盘工厂DiskFileItemFactory对象,用来配置上传组件ServletFileUpload;
DiskFileItemFactory factory = new DiskFileItemFactory();
DiskFileItemFactory类的常用方法
| 方法 | 返回值 | 描述 |
| setSizeThrehold() | void | 该方法需要传入一个int型参数,用来设置最大内存大小(byte为单位) |
| setRepositoryPath() |
void |
该方法需要传入一个String型参数,用来设置临时文件目录 |
| getRepository() | File | 获取保存临时文件地址 |
2、其次,创建ServletFileUpload实例,即创建上传文件的句柄。
可通过DiskFileItemFactory实例构造ServletFileUpload对象,代码如下:
ServletFileUpload upload = newServletFileUpload(factory);
| 方法 | 返回值 | 描述 |
| isMultipartContent() | boolean | 检查是否是一个文件上传请求 |
| parseRequest() | List | 从request对象中得到所有上传域表单 |
四、使用例子(servlet部分代码)
下面就给出一个简单的文件上传的例子。
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>file upload demo</title>
8 </head>
9 <body>
10 <form action="/servletPro/FileUpload" method="post" enctype="multipart/form-data">
11 <table width="31%" border="0" align="center">
12 <tr bgcolor="#CCCCCC">
13 <th height="26">请选择要上传的附件:</th>
14 </tr>
15 <tr>
16 <td><label>上传文件</label><input type="file" name="file" /></td>
17 </tr>
18 <tr bgcolor="#CCCCCC">
19 <td height="23"><input type="submit" name="submit" value="上传"></td>
20 </tr>
21 </table>
22 </form>
23 <%
24 if (request.getAttribute("result") != null) {
25 out.println("<script>alert('" + request.getAttribute("result") + "');</script>");
26 }
27 %>
28 </body>
29 </html>
2、在项目WebContent/目录下创建一个uploadfiles文件夹用来存放上传的文件。
3、创建一个名为FileUpload的servlet,代码如下:
package com.hyman.servlet;
public class FileUpload extends HttpServlet {
private static final long serialVersionUID = 1L;
private String uploadFileDir;
private ServletContext sc;
public FileUpload() {
super();
}
@Override
public void init(ServletConfig config) throws ServletException {
super.init(config);
uploadFileDir = config.getInitParameter("uploadDir");
sc = config.getServletContext();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String simpleFileName = "";
String fileDir = sc.getRealPath("/") + uploadFileDir;
String message = "文件上传成功!";
if (ServletFileUpload.isMultipartContent(request)) {
DiskFileItemFactory factory = new DiskFileItemFactory();
factory.setSizeThreshold(20 * 1024); //20KB
factory.setRepository(factory.getRepository());
ServletFileUpload upload = new ServletFileUpload(factory);
int maxSize = 2 * 1024 * 1024; //2MB
List formlists = null;
try {
formlists = upload.parseRequest(request);
} catch (FileUploadException e) {
e.printStackTrace();
}
Iterator iterator = formlists.iterator();
while (iterator.hasNext()) {
FileItem formitem = (FileItem) iterator.next();
if (formitem.isFormField()) {
String fieldname = formitem.getFieldName();
//这里是非上传文件的表单域,可以通过formitem.getString(fieldname)来获取相应表单字段的值
} else {
//这里是上传文件的表单域
String name = formitem.getName();
if (formitem.getSize() > maxSize) {
message = "您上传的文件太大,请重新选择不超过2M的文件";
break;
}
String fileSize = new Long(formitem.getSize()).toString();
if (name == null || "".equals(name) && "0".equals(fileSize))
continue;
int delimiter = name.lastIndexOf("\\");
simpleFileName = delimiter == -1 ? name : name.substring(delimiter + 1);
File saveFile = new File(fileDir, simpleFileName);
try {
formitem.write(saveFile);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
request.setAttribute("result", message);
request.getRequestDispatcher("FileUpload.jsp").forward(request, response);
}
}
4、在web.xml中进行初始化参数配置:
1 <servlet>
2 <description></description>
3 <display-name>FileUpload</display-name>
4 <servlet-name>FileUpload</servlet-name>
5 <servlet-class>com.hyman.servlet.FileUpload</servlet-class>
6 <init-param>
7 <param-name>uploadDir</param-name>
8 <param-value>uploadfiles\</param-value>
9 </init-param>
10 </servlet>
11 <servlet-mapping>
12 <servlet-name>FileUpload</servlet-name>
13 <url-pattern>/FileUpload</url-pattern>
14 </servlet-mapping>
五、使用过程中遇到的一些问题及解决办法
1、每个用户上传的文件需要存放在以用户uid通过MD5加密命名的文件夹中,即需先在uploadfiles目录下创建一个对应的文件夹再将文件存该文件夹中。
可以如下实现:
1 String fileDir = sc.getRealPath("/") + uploadFileDir;
2 //创建文件夹的路径
3 String folderName = fileDir + "328ae78f9298e9a00c9dfa673280c17d";
4 File folder = new File(folderName);
5 if (!folder.exists()) {
6 folder.mkdir();
7 }
2、路径中的"/"改为"\"
可以使用:folderName = folderName.replaceAll("/", "\\\\");
路径中的"\"改为"/"
可以使用:folderName = folderName.replaceAll("\\\\", "/");
3、在上传文件的时候还提交了非上传文件的表单,则读取文件和其他表单数据的先后顺序跟jsp文件中表单的前后顺序有关。
4、在项目中,可能同时上传多份文件,而这些文件的全路径需以一个特定的连接符连接起来存到数据库中。我在项目中碰到这么一个问题,只要服务器重新启动,第一次上传文件保存的路径集没错,但是之后的上传都会出现路径集中附带之前上传的文件路径...而重启服务器之后的第一次上传又不会出现这种情况。这个问题着实纠结了很久,后来看到网上有介绍说可能是缓存的问题formitem用完要调用delete()方法清空缓存,这样处理之后还是没能解决这个问题。后来突然发现自己将保存每次上传路径集的String对象定义成了当前servlet的一个成员变量!!!servlet是单例的,该servlet只要被服务器创建了就会一直保存在服务器中,所以保存每次上传路径集的String对象会将每次上传的文件全都叠加起来。
使用commons-fileUpload组件上传文件的更多相关文章
- EasyUI 关于IE使用window组件上传文件
有时候IE会对使用window组件上传文件(第二次)不生效,解决方案是: 将该window每次打开的时候,使用: $('#adUploadWindow').window('refresh', 'pan ...
- Commons.net FTPClient 上传文件
使用 Commons.net FTPClient 上传 文件打不开. 原因,FTPClient 默认使用 ASCII 传输文件,FTP.ASCII_FILE_TYPE; 需要在登录代码后重新指定传输方 ...
- asp.net中FileUpload得到上传文件的完整路径
asp.net中FileUpload得到上传文件的完整路径 Response.Write("完整路径:" + Server.MapPath(FileUpload1.PostedFi ...
- 关于commons-fileupload组件上传文件中文名乱码问题
java web开发,常用到的文件上传功能,常用的commons-fileupload和commons-io两个jar包.关于如何使用这两个jar来完成文件上传的功能,这里不做详解.使用commons ...
- javaweb-番外篇-Commons-FileUpload组件上传文件
一.Commons-FileUpload简介 Commons-FileUpload组件 Commons是Apache开放源代码组织的一个Java子项目,其中的FileUpload是用来处理HTTP文件 ...
- Extjs 使用fileupload插件上传文件 带进度条显示
一.首先我们看看官方给出的插件的解释: 一个文件上传表单项具有自定义的样式,并且可以控制按钮的文本和 像文本表单的空文本类似的其他特性. 它使用一个隐藏的文件输入元素,并在用户选择文件后 在form提 ...
- ASP.NET中扩展FileUpload的上传文件的容量
ASP.NET中扩展FileUpload只能上传小的文件,大小在4MB以内的.如果是上传大一点的图片类的可以在web.config里面扩展一下大小,代码如下 <system.web> &l ...
- 在Struts2中使用Uploadify组件上传文件
Uploadify是一个基于Jquery的文件上传组件,官网http://www.uploadify.com/可以在官网获得该组件,运行演示示例,下载帮助文档. 作为Web前端的增强技术,Jq ...
- django Form组件 上传文件
上传文件 注意:FORM表单提交文件要有一个参数enctype="multipart/form-data" 普通上传: urls: url(r'^f1/',views.f1), u ...
随机推荐
- c语言全局变量
1.全局变量 #include <stdio.h> int L,n; void solve() { // printf("%d",L); printf("%d ...
- python打印详细的异常信息
#!/usr/bin/env python #coding=utf-8 import traceback try: 1/0 except Exception, e: print e print tra ...
- github使用成长记
学校里一直都有自己写一些网页,一方面为了学习熟练技能,另一方面也是兴趣所在.但是独乐乐不如众乐乐,一直向往有那么一个平台能把自己做得东西分享给广大网友,并且想借着分享的契机和各位程序猿交流学习心得(这 ...
- oracle pl/sql简介、块、过程
pl/sql语言是oracle在sql上扩展的语言.1 过程.函数.触发器是在pl/sql编写2 过程.函数.触发器是在oracle中3 pl/sql的语句可以在java中直接调用 简单介绍 在sql ...
- mysql中文乱码的完美解决方案
问题描述: mysql插入中文时显示为乱码或"?"号 解决方案: 修改mysql的my.ini配置 [mysql] default_character_set=utf8 [mysq ...
- mysql千万级测试1亿数据的分页分析测试
本文为本人最近利用几个小时才分析总结出的原创文章,希望大家转载,但是要注明出处 http://blog.sina.com.cn/s/blog_438308750100im0e.html 有什么问题可以 ...
- Codevs 2307[SDOI2009]HH的项链
同题: Codevs 2307 HH的项链 BZOJ 1878 HH的项链 洛谷 1972 HH的项链 2009年省队选拔赛山东 时间限制: 1 s 空间限 ...
- 微信小程序(原名微信应用号)开发工具0.9版安装教程
微信小程序全称微信公众平台·小程序,原名微信公众平台·应用号(简称微信应用号) 声明 微信小程序开发工具类似于一个轻量级的IDE集成开发环境,目前仅开放给了少部分受微信官方邀请的人士(据说仅200个名 ...
- g++ 编译和链接(转)
传统意义上的编译程序分两步走 —— 编译和链接: 1.编译(compile):指用编译器(compiler)将源代码(source code)生成二进制目标文件(object file),在Windo ...
- SQLite CRUD操作
SQLite CRUD操作代码实例: 1:首先创建一个继承了SQLiteOpenHelper类的MyDatabaseHelper类.实现他的onCreate(SQLiteDatabase db) on ...