1 创建监听的实体类
public class FileUploadStatus {
private long bytesRead;//已上传大小(b)
private long contentLength;//总大小
private int items; //正在上传的第几个文件
private boolean flag;//是否上传完成
private long startTime = System.currentTimeMillis(); // 开始上传的时间,用于计算上传速度等
private int percent; // 上传百分比
private double velocity; //上传的速率
public double getVelocity() {
return velocity;
}
public void setVelocity(double velocity) {
this.velocity = velocity;
}
public long getBytesRead() {
return bytesRead;
}
public void setBytesRead(long bytesRead) {
this.bytesRead = bytesRead;
}
public long getContentLength() {
return contentLength;
}
public void setContentLength(long contentLength) {
this.contentLength = contentLength;
}
public int getItems() {
return items;
}
public void setItems(int items) {
this.items = items;
}
public boolean isFlag() {
return flag;
}
public void setFlag(boolean flag) {
this.flag = flag;
}
public long getStartTime() {
return startTime;
}
public void setStartTime(long startTime) {
this.startTime = startTime;
}
public int getPercent() {
return percent;
}
public void setPercent(int percent) {
this.percent = percent;
}
}
2 创建监听类
public class MyProgressListener implements ProgressListener {
private HttpSession session;
private FileUploadStatus status;
public MyProgressListener(HttpServletRequest req) {
this.session = req.getSession();
status = new FileUploadStatus();
status.setFlag(false);
session.setAttribute("uploadStatus",status);
}
@Override
public void update(long pBytesRead, long pContentLength, int pItems) {
Object attribute = session.getAttribute("uploadStatus");
if(null == attribute){
status.setFlag(false);
session.setAttribute("uploadStatus",status);
}else{
status = (FileUploadStatus)attribute;
}
status.setBytesRead(pBytesRead);
status.setContentLength(pContentLength);
status.setItems(pItems);
//上传开始时间
long startTime = status.getStartTime();
long currentTime = System.currentTimeMillis(); //现在时间
long time = (currentTime - startTime)/ 1000; //已传输的时间 单位:s
if ((Long.valueOf(pBytesRead) * 100 / Long.valueOf(pContentLength) <= 100)) {
// 生成当前上传进度的公式,加入判断条件的含义在于不需要重复计算
int percent = (int) (Long.valueOf(pBytesRead) * 100 / Long.valueOf(pContentLength));
status.setPercent(percent);
}
//传输速度单位:byte/s
double velocity = ((double)status.getBytesRead()/1000) / (double)time;
status.setVelocity(velocity);
//估计总时间
double totalTime = status.getContentLength()/velocity;
//估计剩余时间
double timeLeft = totalTime - time;
if(pBytesRead == pContentLength){
status.setFlag(true);
}else{
status.setFlag(false);
}
session.setAttribute("uploadStatus", status);
}
}
3 自己重新实现strtus2的MultiPartRequest接口。因为strtus2框架的实现类没有注入监听器,所以需要自己手动实现。(具体为啥要实现,网上有比较多的理论,请自行搜索查看),只需要重新实现一个方法即可。
private List parseRequest(HttpServletRequest servletRequest, String saveDir) throws FileUploadException {
DiskFileItemFactory fac = createDiskFileItemFactory(saveDir);
ServletFileUpload upload = new ServletFileUpload(fac);
FileUploadStatus status = new FileUploadStatus();
servletRequest.getSession().setAttribute(“uploadStatus”, status);
// 设置上传进度的监听
upload.setProgressListener(new MyProgressListener(servletRequest));
upload.setSizeMax(maxSize);
return upload.parseRequest(createRequestContext(servletRequest));
}
剩下的方法和org.apache.struts2.dispatcher.multipart.JakartaMultiPartRequest 一样(copy即可)。
4 修改strtus2的配置文件strtus.xml,添加
<bean type="org.apache.struts2.dispatcher.multipart.MultiPartRequest" name="myRequestParser" class="com.run.wzgl.interceptor.MyRequestParser" scope="default" optional="true"></bean>
<constant name="struts.multipart.parser" value="myRequestParser" />
5 实现获取上传进度的类
public void uploadProgress() throws Exception {
System.out.println("获取上传文件进度信息");
JSONObject json = new JSONObject();
Object attribute = ServletActionContext.getRequest().getSession().getAttribute("uploadStatus");
FileUploadStatus status = null;
if(null == attribute){
System.out.println("session中没有fileupload信息1");
json.put("progress", status);
this.outPrintJson(json);
}else{
System.out.println("session中有fileupload信息2"+status.toString());
status = (FileUploadStatus)attribute;
}
json.put("progress", status);
this.outPrintJson(json);
}
6 前端实现。每隔100毫秒请求上传进度的实现类(具体实现要看前端的设计)
//循环查看状态
var t = setInterval(function(){
$.ajax({
url: ‘uploadProgress.do’,
type: ‘GET’,
dataType: ‘json’,
async:false,
cache:false,
success: function (data) {
var byteRead = data.progress.bytesRead;
var contentLength = data.progress.contentLength;
var percent = data.progress.percent;
if(byteRead==contentLength){
clearInterval(t);
}
alert(“已上传文件”+percent+"%");
},
error: function(){
console.log(“error”);
}
});
}, 100);