您的位置:首页 > 其它

Jakarta-Common-FileUpload使用简单入门

2008-12-06 11:51 344 查看
common-fileupload是jakarta项目组开发的一个功能很强大的上传文件组件,可以支持多个文件同时上传,同时也可以除了将上传文件保存为文件之外,还可以将上传的文件数据提取保存至数据库中,甚至你可以通过调用其中提供的API,在程序代码中获得上传文件的内容,这样你就可以处理这些数据了,这个当然与具体的应用有关了。
这里只讲common-fileupload的简单使用入门,一并解决上传文件中文件名为中文时,上传之后文件名显示乱码的问题,这个解决方法很简单,在示例程序代码中的注释中有详细的描述,查看程序就可以明白了。同时这里的示例代码中,只提供了一个文件上传框的显示,但是在后台提供了多个文件上传的读取支持的,只要能够基本明白这个上传方法,做成多个文件上传也不成问题。
另外还需说明的是,对于上传文件,通常前台上传文件至后台时,后台是一个Servlet来处理请求,而Servlet处理请求中,通常会有返回页面,所以如果要做到界面显示,而不会让用户感觉有因为上传而产生的刷屏的样子,应该做一个类似于AJAX的表现,来进行局部刷新,不过AJAX本身而言,并不支持form的post方式的文件提交,所以不能用AJAX来进行上传文件的局部刷新。通常比较好的一种做法是在你的网页中内嵌一个iframe,在iframe里面做一个form,以进行文件上传的提交。具体示例代码见下。
本次的上传使用的Common-FileUpload的版本是最新版,即1.2.1版,与网上的其它代码相比,改了很多的使用方式,虽然可以兼容以前的调用方式,不过已经不推荐了,这里的示例代码使用最新的调用方式。它的下载地址是:http://commons.apache.org/fileupload/,另外你可以通过下载地址中的User Guide链接,找到具体如何使用的方法,当然如果你对英文不感兴趣的话,可以看下面的示例代码,看明白后,再去看那个User Guide,可能收获会更大些。
好了,不说废话了,下面贴出示例代码:
WEB页面:
文件名:uploadtest.html
<html>
<head>
<title>文件上传</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<p>
<b>文件上传</b>
</p>
<br/>
<br/>
<div id="fileSendDiv">
<iframe width="100%" height="35" frameborder="0" id="show" name="show" src="uploadfile.jsp" scrolling="no" style="frameborder:0" align="left"></iframe>
</div>
<br/>
<br/>
<br/>
<br/>
<p>
<b>刷新的是iframe,父页面不会改变</b>
</p>
</body>
</html>
该页面注意的是iframe的使用,刷新的会是iframe,iframe指向了一个新的文件,文件名叫:uploadfile.jsp,这个才是真正的上传文件的内容表现,你可以将这个文件作为工具类型的文件,只要在上传文件中通过iframe引用这个文件即可(uploadtest.html与uploadfile.jsp处于同一个目录中)。
上传显示文件代码如下:
文件名:uploadfile.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>上传文件</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<script language="JavaScript" type="text/javascript">
function upload()
{
var filename = document.tab.uploadfile.value;
if (filename=='')
{
alert("没有选择要上传的文件,请选择!");
return;
}

document.tab.action = "FileUpload";//提交上传为文件时,所指向的servlet配置的Servlet动作
document.tab.target="show";//指向iframe的ID,即刷新页面返回时所指的地方。
document.tab.submit();

}
</script>
</head>
<body style="margin:0px;">
<form name="tab" method="post" action="" enctype="multipart/form-data">
<input type="file" id="uploadfile" name="uploadfile" style="border:1px solid black;" >
<input type="button" name="up" value="上传" style="border:1px solid black;height:20px;" onClick="upload()">
</form>
</body>
</html>
需要明确的是该上传文件当调用upload之后,其返回所指向的是ID为show表单,查看uploadtest.html中的iframe发现,指的就是这个iframe的ID,所以说当后台的Servlet有返回时,刷新的也只是这个iframe,而不会影响整个父页面的显示效果。

下面是后台Servlet的源代码:
文件名:UploadFileTest.java

package com.uploadtest;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Iterator;
import java.util.List;

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.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

public class UploadFileTest extends HttpServlet {
private static final long serialVersionUID = 1L;

private static final String CONTENT_TYPE = "text/html; charset=utf-8";

//Process the HTTP Post request
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String path = request.getContextPath();
//WEB形式的表现地址,示例:http://127.0.0.1:8080/uploadtest/
String basePath = request.getScheme() + "://" + request.getServerName()
+ ":" + request.getServerPort() + path + "/";
//获得本地地址,示例如:c://tomcat/webapp/
String temp = getServletContext().getRealPath("/") + "upload/temp"; //临时目录
String loadpath = getServletContext().getRealPath("/") + "upload"; //上传文件存放目录
response.setContentType(CONTENT_TYPE);
PrintWriter out = response.getWriter();
try {
//Create a factory for disk-based file items
DiskFileItemFactory factory = new DiskFileItemFactory();
//Set factory constraints设置最多只允许在内存中存储的数据,单位:字节
factory.setSizeThreshold(4096);
//设置一旦文件大小超过getSizeThreshold()的值时数据存放在硬盘的目录(缓存)
factory.setRepository(new File(temp));
//Create a new file upload handler
ServletFileUpload upload = new ServletFileUpload(factory);
// Set overall request size constraint设置允许用户上传文件大小,单位:字节,这里设为5m
upload.setSizeMax(5 * 1024 * 1024);
//Parse the request
List /* FileItem */fileItems = upload.parseRequest(request);
//开始读取上传信息
// 依次处理每个上传的文件
Iterator iter = fileItems.iterator();
while (iter.hasNext()) {
FileItem item = (FileItem) iter.next();
//忽略其他不是文件域的所有表单信息
if (!item.isFormField()) {
String name = item.getName();
long size = item.getSize();
if ((name == null || name.equals("")) && size == 0)
continue;
name = name.substring(name.lastIndexOf("//") + 1);//从全路径中提取文件名
//处理中文编码问题,前台是UTF-8,所以这里需要对应上,如果前台是gb2312的话,这里也应该是gb2312
name = new String(name.getBytes(), "utf-8");
try {
//保存上传的文件到指定的目录
//在下文中上传文件至数据库时,将对这里改写
File fNew = new File(loadpath, name);
item.write(fNew);
//out.print(name + " " + size + "");
response.sendRedirect(basePath + "uploadfile.jsp");//返回刷新页面,即返回iframe
}
catch (Exception e) {
e.printStackTrace();
out.println(e);
}
}
}
}
catch (Exception e) {
e.printStackTrace();
}
}
}
具体的调用说明,见源文件中的注释
最后就剩下web.xml的配置了,下面是示例:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> <display-name>UploadFile</display-name>
<servlet>
<description></description>
<display-name>FileUpload</display-name>
<servlet-name>FileUpload</servlet-name>
<servlet-class>
com.uploadtest.UploadFileTest
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>FileUpload</servlet-name>
<url-pattern>/FileUpload</url-pattern>
</servlet-mapping>
</web-app>
好了,一个完整的使用Common-FileUpload的例子就结束了。
最后要提一点,就是这个上传组件中,在解析上传文件时,会读取上传文件的内容的,有时在应用中,比如WEB呼叫中心方面,WEB端上传的文件会被远端的人员接收,但是有时的情况下,远端服务人员并不一定希望接收WEB端发过来的文件,所以即便是远端服务人员拒绝了接收文件,但是这个上传组件却是已经读取了文件的内容至缓存中了,也就是说多做了一步。并且即便是远端服务人员愿意接收文件,它也是有延迟的,过程是先从WEB中接收文件至缓存中,再从缓存中提取数据传至远端的服务人员。估计可以通过改变这个上传组件的源代码,来回避上面所说的问题,不过需要对源代码有一定的研究。
至于用到该上传组件的一些高级功能(如要做一个上传进度条的显示),可以看它提供的User Guide,进行自身功能的定义了,本文只做入门级介绍。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: