好久没有写东西,最近在做个项目,要用到文件h 传的,以前虽然也做上传,但是总觉得不好用 ,现在和队友合作做了一个带进度条的上传,觉得还行~~和大家分享一下。
首先说一下大概是这样实现的,在我们平时的上传表单里面,除了文件上传之外,也许还有其他的信息需要填写的,这样问题就来了:点击上传按钮之后,这个表单都封装并提交上去了,在上传完成后整个页面就跳转了。而且也不利于我们验证用户输入。很多人这样做的,把这2个操作分开,当然这样也行。。。
我们这样做:一个普通页面(可以用于填写所有信息的),一个文件上传页面,一个上传成功页面(这个不怎么重要)
然后关键的就是:把文件上传的页面嵌入到普通页面里面去,相当于说文件上传实际是由上传页面独立完成,信息填写页面也独立成功信息填写,这里我们用iframe。
不多说,上代码:
1、处理上传的Action
package org.yzsoft.upload.action;
import java.io.*;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionSupport;
public class UploadAction extends ActionSupport {
private static final int BUFFER_SIZE = 100;// 上传的字符流大小(单位:字节)
// 用File来封装上传文件域对象
private File file;
// 保存文件的目录路径(通过自动注入)
private static String ext; //文件后缀
private static String fileFileName;
private static float percent = 0;//百分比
// 自己封装的一个把源文件对象复制成目标文件对象
private static void copy(File src, File dst) {
InputStream in = null;
OutputStream out = null;
float completedSize = 0;//已经上传的大小
float fileSize = 0;//文件总大小
try {
in = new BufferedInputStream(new FileInputStream(src), BUFFER_SIZE);
out = new BufferedOutputStream(new FileOutputStream(dst), BUFFER_SIZE);
fileSize = in.available();
byte[] buffer = new byte[BUFFER_SIZE];
int len = 0;
while ((len = in.read(buffer)) > 0) {
out.write(buffer, 0, len);
completedSize += (long) len;
percent = completedSize / fileSize * 100;//百分比计算
}
} catch (Exception e) {
System.out.println(e);
} finally {
if (null != in) {
try {
in.close();
} catch (IOException e) {
System.out.println(e);
}
}
if (null != out) {
try {
out.close();
} catch (IOException e) {
System.out.println(e);
}
}
}
}
public String sumPre() { //计算后百分比输回页面
try {
PrintWriter out = ServletActionContext.getResponse().getWriter();
System.out.println(getFileFileName() + " filename");
out.print(percent);
} catch (IOException e) {
System.out.println("异常:" + e);
}
return null;
}
//上传的方法
public String upload() {
try {
if (percent >= 99.9) {//这里保险起见我们设百分比》99.9就清0,避免进度条到了100%就停在那里不动的尴尬
percent = 0;
}
File srcfile = this.getFile();// 自动注入的方法取得文件域的对象
// 根据服务器的文件保存地址和原文件名创建目录文件全路径
String uploadPath = ServletActionContext.getServletContext().getRealPath("upload");// 上传路径
ext = fileFileName.substring(fileFileName.lastIndexOf(".")).toLowerCase();// 取得后缀
System.out.println("取得后缀 " + ext);
File dstFile = new File(uploadPath, fileFileName);
copy(srcfile, dstFile);
} catch (Exception e) {
System.out.println(e);
}
return "success";
}
/**************/
public File getFile() {
return file;
}
public void setFile(File file) {
this.file = file;
}
public String getFileFileName() {
return fileFileName;
}
public void setFileFileName(String fileFileName) {
this.fileFileName = fileFileName;
}
}
2、上传表单页面(就是我们平时普通的表单页面,样式有点乱。不理它了。嘻嘻~~~)
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'index.jsp' starting page</title>
</head>
<body>
<form action="upload_doCreate.action" method="post" name="form" >
<table id="table2" width="99%" border="0" cellpadding="0" cellspacing="0">
<tr>
<th>文件上传</th>
</tr>
<tr>
<td ><table border="0" cellpadding="0" cellspacing="0" style="width:100%">
<tr>
<td align="left"> </td>
</tr>
<tr>
<td width="100%">
<table border="0" cellpadding="2" cellspacing="1" style="width:100%">
<tr>
<td align="right">文件名:</td>
<td><input type="text" id="filename" value=""/></td>
</tr>
<tr>
<td align="right">文件路径:</td>
<td><iframe style="width: 400px;height: 25px" scrolling='no' frameborder='0' resizable='no' allowtransparency='true' cellspacing='0' border='0' src='fileupload.jsp' id='iframeupload'></iframe></td>
</tr>
</table>
<br />
</td>
</tr>
</table></td>
</tr>
<tr>
<td colspan="2" align="center" height="50px">
<input type="Submit" name="Submit" value="保存" class="button" />
<input type="button" name="Submit2" value="返回" class="button" οnclick="window.history.go(-1);"/></td>
</tr>
</table>
</form>
</body>
</html>
3、上传进度条页面(注意,这个是用一个iframe的源文件链接实现的)
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme() + "://"
+ request.getServerName() + ":" + request.getServerPort()
+ path + "/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<script type="text/javascript" src="jquery-1.6.2.min.js">
</script>
<style type="text/css">
<!--
body {
margin-left: 0px;
margin-top: 0px;
margin-right: 0px;
margin-bottom: 0px;
font-size: 14px;
}
-->
</style>
<script type="text/javascript">
function aa() {
$("#div1").hide();
$("#div2").show();
$.post("sumPre", {}, function(data) {//AJAX方式发送请求到Action的sumPre方法,计算后将百分比data返回来
$("#img").attr("width", parseInt(data) * 1.5);//设置进度条长度,这里*1.5只是为了把进度条显示长一点,好看一点
$("#p").html(parseInt(data) + "%");//进度百分比
});
window.setTimeout("aa()", 10);//定时执行
}
</script>
</head>
<body>
<div id="div1">
<form name='aform1' method='post' action="fileUpload.action"
enctype="multipart/form-data">
<input name='file' type='file' />
<input type="submit" value="上传" οnclick="return aa();" />
</form>
</div>
<div id="div2" style="width: 400px; display: none;">
正在上传...
<img alt="" src="13221820.gif" width="16" height="16">
<img id="img" alt="" src="percent.jpg" width="1" height="5">
<span id="p" style="position: absolute; right: 30%; top: 0px;"></span>
</div>
</body>
</html>
4、上传成功后的页面(就是一个简单的页面)
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<style type="text/css">
<!--
body {
margin-left: 0px;
margin-top: 5px;
margin-right: 0px;
margin-bottom: 0px;
font-size: 14px;
}
-->
</style>
</head>
<body>
上传成功
</body>
</html>
5、Struts.xml 配置文件
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<!-- Author: yzx -->
<struts>
<constant name="struts.multipart.maxSize" value="61440000000"></constant>
<package name="fileUpload" namespace="/" extends="struts-default">
<action name="fileUpload" class="org.yzsoft.upload.action.UploadAction" method="upload">
<result name="success">/filejd.jsp</result>
</action>
<action name="sumPre" class="org.yzsoft.upload.action.UploadAction" method="sumPre">
</action>
</package>
</struts>
接着:
我们在本机调试上传的时候,网页可能会有所卡顿,这个没关系,我们绑到服务器上就正常了,主要是浏览器处理文件的时候硬件性能问题。
总的来说,这个上传还是比较简单的(至少我这样认为~_~)
最后附上源码:欢迎大家多多交流,小弟这里先谢过啦~~~嘻嘻~~