该上传我也是在网上找了很多资料大多都是东拼西凑的组一起,也没见一个能用的。
在此根据自己的理解就组合了一套成功的带进度条的上传。
相信有这么一套成功的代码不管在什么样的框架,只要它用Commons-Fileupload就可以实现带进度条的上传
1.必须申明如此bean才能确保HttpServletRequest可以被转型成MultipartHttpServletRequest
<bean id="multipartResolver" class="com.xx.fileupload.CommonsMultipartResolverExt">
<property name="defaultEncoding" value="UTF-8" />
</bean>
2.必须重写org.springframework.web.multipart.commons.CommonsMultipartResolver中的parseRequest方法这里我写了一个类CommonsMultipartResolverExt进行了对CommonsMultipartResolver的继承,并重写了parseRequest方法。该方法必须加入自己定义的监听器
public MultipartParsingResult parseRequest(HttpServletRequest request) throws MultipartException {
String encoding = "utf-8";
FileUpload fileUpload = prepareFileUpload(encoding);
fileUpload.setProgressListener(new FileProgressListener(request));
try {
List<FileItem> fileItems = ((ServletFileUpload) fileUpload).parseRequest(request);
return parseFileItems(fileItems, encoding);
}
catch (FileUploadBase.SizeLimitExceededException ex) {
throw new MaxUploadSizeExceededException(fileUpload.getSizeMax(), ex);
}catch (FileUploadException ex) {
throw new MultipartException("Could not parse multipart servlet request", ex);
}
}
3.apache上传组件中只提供了一个接口ProgressListener,所以我们必须要去实现它。这里我建立了监听器FileProgressListener去实现ProgressListener,
该监听器的构造方法要求传入一个request(目的为了写入进度session值)
它要求必须实现一个方法名为update的方法,参数有三个
参数一bytesRead:已上传的字节
参数二contentLength:客户要上传的文件总字节数
参数三items读写的状态 0未被读取 1为已经被读取
public void update(long bytesRead, long contentLength, int items) {
BigDecimal read = new BigDecimal(bytesRead+"");
BigDecimal max = new BigDecimal(contentLength+"");
Double result = read.divide(max,3,BigDecimal.ROUND_HALF_UP).doubleValue()*100;
request.getSession().setAttribute("percent", result.intValue());
}
由于update方法中涉及到大数值,所以这里用了BigDecimal
其它的应该自己能想到怎么做了吧。
实例中有jsp的代码详细的还得看看jsp怎么通过异步去获取数据
由于时间问题我没有做成一个完美的上传组件。有了这样的上传我估计用js封装一个上传组件很容易的就成功了。
注意:不知道什么原因请求名不能为upload,如果为upload时总会报强制类型转换异常
下面介绍jsp的代码,jsp中用了jquery进行ajax异步获取上传进度值,提交表单前执行一个函数,该函数通过ajax获取服务器端的session值,在未达到100%时每隔1秒去调用一次。
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'upload.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">
<script type="text/javascript" src="js/core/jquery-1.8.2.min.js"></script>
<SCRIPT type=text/javascript>
function doProgressLoop(prog, max, counter) {
var x = $("#text").html();
x = x.replace("%","");
var y = parseInt(x);
if (!isNaN(y)) {
prog = y;
}
counter = counter + 1;
if (prog < 100) {
setTimeout("getProgress()", 1000);
setTimeout("doProgressLoop(" + prog + "," + max + "," + counter
+ ")", 1500);
$("#text").html(prog+"%");
}
}
function getProgress() {
$.ajax({
type : "post",
dataType : "text",
url : "/percent",
data : "",
success : function(data) {
$("#bar").css("width",data*2);
$("#text").html(data+"%");
},
error : function(err) {
}
});
}
function fSubmit(o) {
$(o).attr("disabled",true);
var max = 100;
var prog = 0;
var counter = 0;
getProgress();
doProgressLoop(prog, max, counter);
$("#form1").submit();
}
</script>
</head>
<body>
<div id="progressBar" style="height:25px;width:200px;border:1px solid #888;text-align:center;color:#fff;position:relative;">
<div style="display:block;width:0px;height:25px;z-index:1;position:absolute;background:#ccc;" id="bar"></div>
<div style="display:block;z-index:100;height:25px;position:absolute;line-height:25px;text-align:center;width:200px;color:red;" id="text">0%</div>
</div>
<form name="asdfasdf" action="up" id="form1" method="post" enctype="multipart/form-data">
请选择文件:<input name="filesaa" id="file" type="file"/><br/>
<input type="button" value="上传" οnclick="fSubmit(this)">
</form>
</body>
</html>
下面展示上传的代码,这里我用了springMVC,自己可以改成servlet
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
@Controller
public class UploadController {
@RequestMapping("/up")
public String upload(HttpServletRequest request, ModelMap modelMap,HttpServletResponse res) throws Exception{
String folderPath="d:/ftp/upload/";
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
MultipartFile file = multipartRequest.getFile("filesaa");
InputStream stream = file.getInputStream();
String fileName = file.getOriginalFilename();
String fileNameFull = folderPath +fileName;
OutputStream bos = new FileOutputStream(fileNameFull);
int bytesRead = 0;
byte[] buffer = new byte[8192];
while ((bytesRead = stream.read(buffer, 0, 8192)) != -1) {
bos.write(buffer, 0, bytesRead);
}
bos.close();
stream.close();
return null;
}
@RequestMapping("/percent")
@ResponseBody
public Integer findPercentage(HttpServletRequest request){
HttpSession session = request.getSession();
Object obj = session.getAttribute("percent");
if(obj!=null){
return Integer.parseInt(obj.toString());
}else{
return 0;
}
}
好了,完工。如代码有问题请联系本人
联系QQ:464425024
email:3825221-22388@163.com或464425024@qq.com