摘要 实现批量上传,同时又进度显示和上传速度
1、struts.xml文件配置
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<constant name="struts.multipart.maxSize" value="61440000000"></constant>
<constant name="struts.i18n.reload" value="true" />
<constant name="struts.action.extension" value="html" />
<package name="imgfile" extends="struts-default" namespace="/imgfile">
<global-results>
<result name="notFound">/error/404.jsp</result>
</global-results>
<action name="uploadfilesUpload" class="cn.test.ProgressAction" method="filesUpload"></action>
<action name="uploadgetUploadStatus" class="cn.test.ProgressAction" method="getUploadStatus"></action>
</package>
</struts>
2、 bean类,存储上传文件的序号,已上传大小等信息
package cn.test.bean;
import java.io.Serializable;
@SuppressWarnings("serial")
public class FileUploadStatus implements Serializable {
private int fileIndex;//当前文件序号
private float uploadFileSize;//当前已上传大小
private int percent;//上传进度
private float fileSize;//文件总大小
public int getFileIndex() {
return fileIndex;
}
public void setFileIndex(int fileIndex) {
this.fileIndex = fileIndex;
}
public float getUploadFileSize() {
return uploadFileSize;
}
public void setUploadFileSize(float uploadFileSize) {
this.uploadFileSize = uploadFileSize;
}
public int getPercent() {
return percent;
}
public void setPercent(int percent) {
this.percent = percent;
}
public float getFileSize() {
return fileSize;
}
public void setFileSize(float fileSize) {
this.fileSize = fileSize;
}
}
3、主要代码,action文件
package cn.test;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Calendar;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.struts2.ServletActionContext;
import cn.test.bean.FileUploadStatus;
import com.opensymphony.xwork2.ActionSupport;
@SuppressWarnings("serial")
public class ProgressAction extends ActionSupport {
private static final int IO_SIZE=10;//上传字符流的大小(单位:字节)
private List<File> file;
private List<String> fileFileName;
private List<String> fileContentType;
private float uploadFileSize=0;//已上传大小
private float fileSize=0;//文件总大小
private int percent=0;//进度百分比
/**
* 文件上传
* @param src
* 根文件
* @param dst
* 目标文件
*/
public void uploadFile(File src, File dst, int i){
System.out.println("进入");
uploadFileSize=0;
InputStream in=null;
OutputStream out=null;
FileUploadStatus status=new FileUploadStatus();
HttpServletRequest request=ServletActionContext.getRequest();
HttpSession session=request.getSession();
try {
in=new BufferedInputStream(new FileInputStream(src), IO_SIZE);
out=new BufferedOutputStream(new FileOutputStream(dst), IO_SIZE);
fileSize=in.available();
if((fileSize/1024/1024)>2){
return;
}
byte[] buffer=new byte[IO_SIZE];
int len=0;
while((len=in.read(buffer))>0){
out.write(buffer, 0, len);
uploadFileSize+=len;
percent=(int) (uploadFileSize/fileSize*100);//上传百分比
status.setFileIndex(i);
status.setFileSize(fileSize);
status.setUploadFileSize(uploadFileSize);
status.setPercent(percent);
System.out.println("fileIndex:"+status.getFileIndex()+"fileSize:"+fileSize+"percent:"+percent+"uploadFileSize:"+uploadFileSize);
session.setAttribute("status", status);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if(null!=in){
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(null!=out){
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* 上传文件
* @return
*/
public String filesUpload(){
System.out.println("进入");
try{
String dstPath=ServletActionContext.getServletContext().getRealPath("/fileupload");
Calendar cal=Calendar.getInstance();
int year=cal.get(Calendar.YEAR);
int month=cal.get(Calendar.MONTH)+1;
int day=cal.get(Calendar.DAY_OF_MONTH);
for(int i=0;i<fileFileName.size();i++){
File src=file.get(i);
File dst=new File(dstPath+"/"+year+"/"+month+"/"+day);
if(!dst.exists()){
dst.mkdirs();
}
dst=new File(dst,"\\"+fileFileName.get(i));
uploadFile(src, dst, i);
}
return null;
}catch (Exception e) {
e.printStackTrace();
return "error";
}
}
/**
* ajax获取文件上传进度状态
* @return
*/
public String getUploadStatus(){
System.out.println("ddddd");
HttpServletRequest request=ServletActionContext.getRequest();
HttpSession session=request.getSession();
FileUploadStatus status=(FileUploadStatus) session.getAttribute("status");
if(status!=null){
try{
HttpServletResponse response=ServletActionContext.getResponse();
PrintWriter out=response.getWriter();
out.print("{\"fileIndex\":"+status.getFileIndex()
+",\"percent\":"+status.getPercent()
+",\"uploadFileSize\":"+status.getUploadFileSize()
+",\"fileSize\":"+status.getFileSize()+"}");
System.out.println("{\"fileIndex\":"+status.getFileIndex()
+",\"percent\":"+status.getPercent()
+",\"uploadFileSize\":"+status.getUploadFileSize()
+",\"fileSize\":"+status.getFileSize()+"}");
out.close();
session.removeAttribute("status");
return null;
}catch (Exception e) {
e.printStackTrace();
return "error";
}
}else{
return null;
}
}
public List<File> getFile() {
return file;
}
public void setFile(List<File> file) {
this.file = file;
}
public List<String> getFileFileName() {
return fileFileName;
}
public void setFileFileName(List<String> fileFileName) {
this.fileFileName = fileFileName;
}
public List<String> getFileContentType() {
return fileContentType;
}
public void setFileContentType(List<String> fileContentType) {
this.fileContentType = fileContentType;
}
}
4、前台页面
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
request.setAttribute("bp",basePath);
%>
<%@taglib uri="/struts-tags" prefix="s" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>My JSP 'test1.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<script type="text/javascript" src="./jquery-1.7.1.js"></script>
<body>
<div id="imgDivs">
</div>
<div id="progressBarTips" style="height: 10px; width: 200px; text-align: center; font-size: 12px;"></div>
<br />
<span id="speed" style="font-size: 12px;"></span>
<br />
<form action="${bp}imgfile/uploadfilesUpload.html" method="post" enctype="multipart/form-data" target="upload-target">
<input type="file" name="file" οnchange="perImg(this);" multiple="multiple" accept="image/*"/>
<button type="submit" value="上传" id="sub" οnclick="return showProgress();">上传</button>
</form>
日志:<br/>
<span id="tipsText" style="color: red; font-size: 12px;"></span>
<iframe frameborder="0" style="height: 0px; width: 0px;" id="upload-target" name="upload-target"></iframe>
</body>
</html>
5、javascript代码
<script type="text/javascript">
var imgSum=0;//图片总数
var finished=false;//是否长传完成
var nextUploadFileSize=0;//上一次已上传文件大小
var nowUploadFileSize=0;//当前上传文件大小
var fileIndex=0;//图片序号
function perImg(obj) {
var filepath = ""; //文件路径
var agent = window.navigator.userAgent;
var isIE7 = agent.indexOf('MSIE 7.0') != -1;
var isIE8 = agent.indexOf('MSIE 8.0') != -1;
if (!obj.value.match(/.jpg|.gif|.png|.bmp|.jpeg/i)) {
alert('图片格式无效!');
return;
}
var fileList=obj.files;
alert(fileList.length);
if(fileList.length>6){
alert("一次最多只能上传6张图片!");
}else{
imgSum=fileList.length;
for(var i=0;i<fileList.length;i++){
alert(fileList[i].size);
alert(obj.value);
var file_names=obj.value.replace(/[ ]/g,"").split(",");
var file_size=fileList[i].size;
if(((file_size/1024)/1024)<=2){
var img_div=$("<div/>");
var img_obj=$("<img style='width: 80px; height: 85px; border: 0px;'/>");
$(img_obj).attr("src",window.URL.createObjectURL(fileList[i]));
$(img_div).append(img_obj);
var img_progress=$("<div id='img_progress_"+i+"' style='background-color: red; height: 10px; width: 0px;'></div>")
var img_upload_tip=$("<div id='img_upload_tip_"+i+"' style='height: 10px; width: 100px; text-align: center; font-size: 12px;'></div>");
$("#imgDivs").append(img_div);
$("#imgDivs").append(img_upload_tip);
$("#imgDivs").append(img_progress);
}else{
alert("图片"+file_names[i]+"大于2M");
}
}
}
}
</script>
6、监听js事件
//开启进度监听
function showProgress(){
$("#sub").attr("disabled","disabled");
finished=false;
callBack();
}
//日志方法
function logText(msg){
$("#tipsText").append(new Date().getTime()+":"+msg+"<br/>");
}
//回调函数,获取上传进度信息
function callBack(){
$.post("${bp}imgfile/uploadgetUploadStatus.html",{},function(data){
if(data!=null){
logText("1111111111111111111111111111111111111");
if(data.percent==100 && fileIndex==(imgSum-1)){
logText("2222222222222222222222222222222222222222222");
//最后一张上传完毕,将finished设为true
finished=true;
}else{
finished=false;
}
var width=data.percent+"%";
nowUploadFileSize=data.uploadFileSize;
var speed=((nowUploadFileSize-nextUploadFileSize)/1024/10)*1000;
nextUploadFileSize=data.uploadFileSize;
if(speed>1024){
$("#speed").text("速度:"+(speed/1024).toFixed(1)+"M/秒");
}else{
$("#speed").text("速度:"+speed.toFixed(2)+"K/秒");
}
$("#img_upload_tip_"+data.fileIndex).text(width);
$("#img_progress_"+data.fileIndex).css({width:(data.percent)+"px"});
//非最后一张上传完毕,将下一张图片序号赋值给fileIndex
if(fileIndex!=data.fileIndex && fileIndex!=(imgSum-1)){
logText("333333333333333333333333333333333333333333上传成功!");
$("#img_upload_tip_"+(data.fileIndex-1)).text("上传成功!");
$("#img_progress_"+(data.fileIndex-1)).css({width:"100px"});
}
fileIndex=data.fileIndex;
}
if(finished && fileIndex==(imgSum-1)){
logText("555555555555555555555555555555555555555555555上传成功!");
//最后一张上传完毕,方法终结
$("#img_upload_tip_"+data.fileIndex).text("上传成功!");
$("#img_progress_"+(data.fileIndex-1)).css({width:"100px"});
return;
}else{
logText("66666666666666666666666666666666666666666666");
//迭代隔10毫秒执行回调函数,获取上传进度信息
setTimeout('callBack()',10);
}
},"json");
}
7、运行截图