转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/6073505.html 

一个功能完善的JavaWeb应用,必不可少的一个功能就是文件的上传。无论是用户的头像等,还是用户需要上传的一系列资料,都是通过文件的上传功能实现的。

目前我们实现网站中关于文件的上传功能时,常用的是apache的开源工具common-fileupload以及common-fileupload的依赖包common-io。

下面以一个注册页面的后台程序为例,大致讲解这两个包的使用:

首先,前往apache官网上面下载common-fileupload、common-io这两个包,并放入工程的WEB-INF文件夹的lib目录下。

然后,在网站页面的表单那里设置:

  文件选择按钮为:<input type="file"/>

  表单数据属性设置为:enctype="multipart/form-data"。因为只有使用enctype="multipart/form-data",表单才会把文件的内容编码到HTML请求中。

  原理请移步:http://blog.csdn.net/mazhibinit/article/details/49667511 进行了解。

<form action="upload_do.jsp" method="post" enctype="multipart/form-data">
文件上传栏: <input type="file" size="30" name="upload" />
<input type="submit" value="提交上传" />
</form>

最后,在表单提交的目的jsp文件中使用两个包中的工具类进行文件的提取与保存,一般步骤如下:

1、实例化一个硬盘文件工厂,用来配置上传组件ServletFileUpload的一些基本设定。比如

    DiskFileItemFactory dfif = new DiskFileItemFactory();
// 定义文件上传时的“运输船”大小。文件是一部分一部分上传的,这里设置为4K。当数据读取到4K则写入硬盘的临时文件夹中,清空运输船继续读取。
//文件传输完后,再从临时文件夹转存到实际的保存路径下
dfif.setSizeThreshold(4096);
// 设置存放临时文件的目录如下:获取完整路径——修改路径新建临时文件夹——把临时文件夹设为工厂的默认目录(则工厂获取的内容会默认存放在这里)
String realwebbase = request.getSession().getServletContext().getRealPath("/");
File temp_file = new File(realwebbase+"upload/UploadTemp");
if (!temp_file.exists()) {
temp_file.mkdirs();
}

dfif.setRepository(temp_file);

2、用工厂实例化上传组件,则该组件会使用该工厂实例的一系列配置(如:以多大容量为一次上传文件、临时文件存放处等)

    ServletFileUpload sfu = new ServletFileUpload(dfif);
sfu.setHeaderEncoding("UTF-8");
// 设置上传文件的最大容量
sfu.setSizeMax(MAX_SIZE);

3、从request对象中把上传内容提取到一个list中。从上面引用的博文处可以看到,POST+multipart/form-data的效果是form表单内的内容以键值对的形式提交上去。

    List fileList = null;
try {
fileList = sfu.parseRequest(request);
}
catch (FileUploadException e) { }

4、用迭代器遍历list对象,提取上传内容。上传内容主要分两种:文本与非文本内容(图片、多媒体文件等)

    Iterator fileItr = fileList.iterator();
while (fileItr.hasNext()) {
FileItem fileItem = (FileItem) fileItr.next();
if(fileItem.isFormField()){ //第一种上传内容:普通文本,分别获取键名、值内容即可
String name = fileItem.getFieldName(); //获取键值对的键名
String value = fileItem.getString("UTF-8"); //此处的getString()是指对list的当前元素(键值对)的值,按照参数所指定的解码方式进行解析、获取内容
}else{ //第二种上传内容:非文本,则需要用到流传输来把内容读取、保存到具体的路径下
String path = fileItem.getName(); //获取文件的路径名,用于截取扩展名进行文件类型的判断// 得到文件的大小,用于判断文件大小是否合法
long size = fileItem.getSize();
if ("".equals(path) || size == 0) {
out.println("上传的文件无效!");
out.close();
return;
}
// 得到去除路径的文件名
String t_name = path.substring(path.lastIndexOf("/") + 1);
// 得到文件的扩展名(无扩展名时将得到全名)
String t_ext = t_name.substring(t_name.lastIndexOf(".") + 1); //遍历允许的扩展名数组,看看上传文件的扩展名是否合法。
int i = 0;
       boolean errorflag=true;
while (i < allowedExt.length) {
if (allowedExt[i].equals(t_ext)){
            errorflag=false;
break;
}
i=i+1;
}
if (errorflag) {
out.println("请上传合法文件!");
out.close();
return;
}
            // 用uuid+日期作为文件名的一部分来唯一标识文件
String uuid = UUID.randomUUID().toString();
String today = new SimpleDateFormat("yyyyMMdd").format(new Date());
//生成最终的文件保存完整路径:目录路径+日期+UUID+ . +扩展名
String u_name = realwebbase + "upload/" + today + "/" + uuid + "." + t_ext;

try {
File _today_file = new File(realwebbase + "upload/Uploaded/" + _today); //构建文件目录
if (!_today_file.exists()) {
_today_file.mkdirs();
}
fileItem.write(new File(u_name)); //把当前list元素的值用write流写到创建好的路径下,即实现文件内容的保存了return;
}
catch (Exception e) {
e.printStackTrace();
} }

5、最后,就是把文件的相对路径信息保存到数据库中去,使文件得以在其他文件中通过相对路径进行引用了。

JavaWeb开发之网站实现文件上传功能的更多相关文章

  1. 用c++开发基于tcp协议的文件上传功能

    用c++开发基于tcp协议的文件上传功能 2005我正在一家游戏公司做程序员,当时一直在看<Windows网络编程> 这本书,把里面提到的每种IO模型都试了一次,强烈推荐学习网络编程的同学 ...

  2. MVC5:使用Ajax和HTML5实现文件上传功能

    引言 在实际编程中,经常遇到实现文件上传并显示上传进度的功能,基于此目的,本文就为大家介绍不使用flash 或任何上传文件的插件来实现带有进度显示的文件上传功能. 基本功能:实现带有进度条的文件上传功 ...

  3. Android 实现文件上传功能(upload)

    文 件上传在B/S应用中是一种十分常见的功能,那么在Android平台下是否可以实现像B/S那样的文件上传功能呢?答案是肯定的.下面是一个模拟网站程 序上传文件的例子.这里只写出了Android部分的 ...

  4. PHPCMS_V9 模型字段添加单文件上传功能

    后台有“多文件上传”功能,但是对于有些情况,我们只需要上传一个文件,而使用多文件上传功能上传一个文件,而调用时调用一个文件URL太麻烦了. 使用说明: 1.打开phpcms\modules\conte ...

  5. 配置php.ini实现PHP文件上传功能

    本文介绍了如何配置php.ini实现PHP文件上传功能.其中涉及到php.ini配置文件中的upload_tmp_dir.upload_max_filesize.post_max_size等选项,这些 ...

  6. Spring 文件上传功能

    本篇文章,我们要来做一个Spring的文件上传功能: 1. 创建一个Maven的web工程,然后配置pom.xml文件,增加依赖: <dependency> <groupId> ...

  7. Spring +SpringMVC 实现文件上传功能。。。

    要实现Spring +SpringMVC  实现文件上传功能. 第一步:下载 第二步: 新建一个web项目导入Spring 和SpringMVC的jar包(在MyEclipse里有自动生成spring ...

  8. Node.js新手教程——怎样实现文件上传功能

    作者:zhanhailiang 日期:2014-11-16 本文将介绍怎样使用Node.js实现文件上传功能. 1. 初始化项目信息:npm init [root@~/wade/nodejs/node ...

  9. nodejs 实现简单的文件上传功能

    首先需要大家看一下目录结构,然后开始一点开始我们的小demo. 文件上传总计分为三种方式: 1.通过flash,activeX等第三方插件实现文件上传功能. 2.通过html的form标签实现文件上传 ...

随机推荐

  1. sublime text的扩展插件

    sublime text用作开发编辑器,还缺省二个比较重要功能:跨文件跳转.返回最后一次编辑的位置: 这里有二个插件正好解决此问题:CTags.ChangeList   其它常用的插件,google一 ...

  2. Android:客户端和服务器之间传输数据加密

    Android客户端与服务器进行数据传输时,一般会涉及到两类数据的加密情况,一类是只有创建者才能知道的数据,比如密码:另一类是其他比较重要的,但是可以逆向解密的数据. 第一类:密码类的数据,为了让用户 ...

  3. Eclipse with ADT的安装和使用

    我们从安卓官方网站下载下来的eclipse是捆绑好了ADT的,所以不用自己安装插件. 我现在在这个目录下简历一个空的文件夹--virtual,用来来存放虚拟机. 然后,在我的电脑上右键->属性, ...

  4. layUI 几个简单的弹出层

    导入控件主题 <link rel="stylesheet" href="dist/themes/default/style.min.css" /> ...

  5. 十个 Laravel 5 程序优化技巧

    性能一直是 Laravel 框架为人诟病的一个点,所以调优 Laravel 程序算是一个必学的技能. 接下来分享一些开发的最佳实践,还有调优技巧,大家有别的建议也欢迎留言讨论. 这里是简单的列表: 配 ...

  6. 4.3 使用 SQL 语句操作数据框

    下载并安装 “sqldf” 包 library(sqldf) newData <- sqldf("select * from mtcars where carb=1 order by ...

  7. vim上次和下次光标位置

    ctrl + I 下次光标位置 ctrl + o上次光标位置.

  8. Docker container常用命令

    列出所有的container. docker container ls 启动一个container. docker run –p <host端口>: <container端口> ...

  9. linux设置开机同步时间

    在/etc/init.d/下新建zhjdate脚本,添加如下内容: #!/bin/bash# chkconfig: 345 63 37#chkconfig:345 63 37 (数字345是指在运行级 ...

  10. (纪录片)电的故事 Shock & Awe The Story of Electricity

    简介: 导演: Tim Usborne主演: Jim Al-Khalili类型: 纪录片 / 传记 / 历史官方网站: www.bbc.co.uk/programmes/p00kjq6d制片国家/地区 ...