Struts2 文件上傳進(jìn)度條的實(shí)現(xiàn)實(shí)例代碼
最近在寫(xiě)我們大三項(xiàng)目的一個(gè)視頻文件上傳的頁(yè)面,實(shí)現(xiàn)后臺(tái)對(duì)上傳的進(jìn)度進(jìn)行監(jiān)聽(tīng),然后將監(jiān)聽(tīng)的信息返回給前臺(tái)頁(yè)面。
前臺(tái)的頁(yè)面效果圖:

前臺(tái)進(jìn)度條控件選擇使用easyui 的progressbar控件。
詳細(xì)的使用說(shuō)明參考官網(wǎng)文檔:http://www.jeasyui.com/documentation/index.php
所有需要引入jquery-1.11.1.min.js 以及jquery.easyui.min.js
一.前臺(tái)的代碼:
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ taglib prefix="s" uri="/struts-tags"%>
<%
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%>" rel="external nofollow" >
<title>My JSP 'uploadVideo.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" href="demo.css" rel="external nofollow" />
<link rel="stylesheet" href="easyui.css" rel="external nofollow" />
<link rel="stylesheet" href="icon.css" rel="external nofollow" />
<script type="text/javascript" src="jquery.min.js" ></script>
<script type="text/javascript" src="jquery.easyui.min.js" ></script>
<link rel="stylesheet" href="videoCss/upload.css" rel="external nofollow" />
<script>
$(function() {
var pro=0;
$("#save").click(function(){
saveDate();
setinterval=setInterval(showUploadProgress, 100);
});
function saveDate(){
var form = new FormData(document.getElementById("form"));
$.ajax({
type:"POST",
url:"uploadfile.action",
data:form,
async:false,
cache:false,
processData:false,
contentType:false,
success:function(result){
var msg=result.msg;
$(".msg").text(msg);
},
error:function(){
alert("file異步提交失敗");
}
});
}
function showUploadProgress(){
$.ajax({
type:"GET",
url:"uploadProgress.action",
dataType:"json",
async:false,
cache:false,
success:function(result){
var progressInfo=result.progressInfo;
pro=progressInfo.percent;
if(pro==100){
clearInterval(setinterval);
}
$('#progress').progressbar('setValue', progressInfo.percent);
$('progress-bar-status').find(".speed").text(progressInfo.velocity);
$('progress-bar-status').find(".finished").text("已上傳:"+progressInfo.length+"/"+progressInfo.totalLength);
$('progress-bar-status').find(".remain").text(progressInfo.timeLeft);
},
error:function(result){
alert("error1");
}
});
}
});
</script>
</head>
<body>
<div class="main_wrapper">
<div class="head_wrapper">
<div class="headinside">
<ul>
<li><a href="">主站</a></li>
<li><a href="">視頻欄</a></li>
<li><a href="">資源區(qū)</a></li>
<li><a href="">個(gè)人中心</a></li>
</ul>
</div>
</div><!--head_wrapper結(jié)束-->
<div class="upload_box">
<p id="error">
<s:fielderror name="struts.messages.error.content.type.not.allowed"></s:fielderror>
<s:actionerror/>
<font color="red" class="msg">${msg }</font>
</p>
<div class="uploadInfo">
<span class="title">
當(dāng)前上傳:
<span class="filename">文件名</span>
</span>
<div id="progress" class="easyui-progressbar" style="width:400px;"></div>
<div class="progress-bar-status">
<span class="speed" style="display: none;">當(dāng)前上傳的速度:80.23k/s</span>
<span class="finished">已上傳:10.86M/10.86M</span>
<span class="remain" style="display:none">剩余時(shí)間:00秒</span>
</div>
<div class="videoInfo">
<form method="post" enctype="multipart/form-data" id="form">
<ul>
<li>
<div>
<label for="video1">文件上傳</label>
<input type="file" id="btn_file" name="video"/>
</div>
</li>
<li>
<label for="name">標(biāo)題</label>
<input type="text" name="name" id="name" title="標(biāo)題" placeholder="給你的視頻七個(gè)標(biāo)題名吧"/>
</li>
<li>
<div>
<label for="cate">分類</label>
<select class="cate" id="cate" name="cate">
<option value ="1">傳統(tǒng)文學(xué)</option>
<option value ="2">民間手工藝</option>
<option value="3">節(jié)假日常</option>
</select>
</div>
</li>
<li>
<div>
<label for="tag">標(biāo)簽</label>
<input type="text" name="tag" id="tag" placeholder="請(qǐng)給您的視頻添加相應(yīng)的標(biāo)簽"/>
</div>
</li>
<li>
<div>
<label for="desc" id="label_desc">描述</label>
<textarea name="videoDesc" id="desc" placeholder="請(qǐng)?zhí)砑酉鄳?yīng)的視頻描述" >
</textarea>
</div>
</li>
<input id="save" type="button" value="保存"/>
<!-- <button id="save">保存</button> -->
</ul>
</form>
</div>
</div>
</div>
</div>
<div style="width: 100%;">
<div class="footer" style="width: 100%;">
<div class="inner">
<p class="a_menu">
<a target="_blank" href="#" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >關(guān)于我們</a>
<i class="line">|</i>
<a target="_blank" href="#" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >聯(lián)系合作</a>
<i class="line">|</i>
<a target="_blank" href="#" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >幫助中心</a>
<i class="line">|</i>
<a target="_blank" href="#" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >合伙人計(jì)劃</a>
<i class="line">|</i>
<a target="_blank" href="#" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >版權(quán)聲明</a>
</p>
<p class="center">
<span>江西師范大學(xué)瑤湖校區(qū)</span>
<span>java工作室</span>
<br>
copyright© 大白
</p>
</div>
</div>
</div>
</body>
</html>
二.點(diǎn)擊上傳后,如何獲得文上傳的進(jìn)度信息。
1.自定義一個(gè)UploadListener類實(shí)現(xiàn)org.apache.commons.fileupload中的ProgressListener接口,從而獲得當(dāng)前上傳的文件的已讀取的數(shù)據(jù)長(zhǎng)度,文件總長(zhǎng)度,正在保存第幾個(gè)文件;
2.重寫(xiě)一個(gè)MyMultiPartRequest類,覆蓋org.apache.struts2.dispatcher.multipart.JakartaMultiPartRequest,改寫(xiě)parseRequest方法,在其中為上傳添加監(jiān)聽(tīng)器;
3.定義一個(gè)UploadStatus bean類存放上傳的狀態(tài)信息,并將獲得上傳進(jìn)度信息的UploadStatus對(duì)象存在在Session域中;
4.編寫(xiě)UploadListenAction,獲取Session域中的UploadStatus對(duì)象,進(jìn)行相應(yīng)的數(shù)據(jù)處理,然后將需要的數(shù)據(jù)放入Map中以json的形式返回給jsp;
5.編寫(xiě)UploadFile.action,實(shí)現(xiàn)文件的上傳存儲(chǔ);
三.相對(duì)應(yīng)的代碼。
package video.action;
import org.apache.commons.fileupload.ProgressListener;
public class UploadListener implements ProgressListener {
private UploadStatus status;
public UploadListener(UploadStatus status) {
this.status = status;
}
public void update(long bytesRead, long contentLength, int items) {
// 上傳組件會(huì)調(diào)用該方法
status.setBytesRead(bytesRead); // 已讀取的數(shù)據(jù)長(zhǎng)度
status.setContentLength(contentLength); // 文件總長(zhǎng)度
status.setItems(items); // 正在保存第幾個(gè)文件
}
}
對(duì)于步驟2中MyMultiPartRequest修改后的方法代碼。
protected List<FileItem> parseRequest(HttpServletRequest servletRequest, String saveDir) throws FileUploadException {
UploadStatus status = new UploadStatus(); // 上傳狀態(tài)
UploadListener listner = new UploadListener(status); // 監(jiān)聽(tīng)器
servletRequest.getSession().setAttribute("uploadStatus", status);//將上傳的進(jìn)度狀態(tài)存放進(jìn)Session;
DiskFileItemFactory fac = createDiskFileItemFactory(saveDir);
ServletFileUpload upload = createServletFileUpload(fac);
upload.setProgressListener(listner);// 添加監(jiān)聽(tīng)器
return upload.parseRequest(createRequestContext(servletRequest));
}
package video.action;
public class UploadStatus {
private long bytesRead; // 已經(jīng)上傳的字節(jié)數(shù),單位:字節(jié)
private long contentLength; // 所有文件的總長(zhǎng)度,單位:字節(jié)
private int items; // 正在上傳第幾個(gè)文件
private long startTime = System.currentTimeMillis(); // 開(kāi)始上傳的時(shí)間,用于計(jì)算上傳速度等
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 long getStartTime() {
return startTime;
}
public void setStartTime(long startTime) {
this.startTime = startTime;
}
}
package video.action;
import java.util.HashMap;
import java.util.Map;
import org.apache.struts2.interceptor.SessionAware;
import com.opensymphony.xwork2.ActionSupport;
public class UploadListenAction extends ActionSupport implements SessionAware{
private UploadStatus status;
Map<String,Object> session;
Map<String,String> progressInfo=new HashMap<>();
@Override
public String execute() throws Exception {
// TODO Auto-generated method stub
status=(UploadStatus)session.get("uploadStatus");
if(status!=null){
long startTime = status.getStartTime(); //上傳開(kāi)始時(shí)間
long currentTime = System.currentTimeMillis(); //現(xiàn)在時(shí)間
long time = (currentTime - startTime)/ 1000 + 1; //已傳輸?shù)臅r(shí)間 單位:s
//傳輸速度單位:byte/s
double velocity = ((double)status.getBytesRead()/1000) / (double)time;
//估計(jì)總時(shí)間
double totalTime = status.getContentLength()/velocity;
//估計(jì)剩余時(shí)間
double timeLeft = totalTime - time;
//已經(jīng)完成的百分比
int percent = (int)(100 * (double)status.getBytesRead() / (double)status.getContentLength());
//已經(jīng)完成數(shù)單位:m
double length = ((double) status.getBytesRead())/1024/1024;
//總長(zhǎng)度 單位:m
double totalLength = ((double) status.getContentLength())/1024/1024;
progressInfo.put("percent", String.valueOf(percent));
progressInfo.put("velocity", String.valueOf(velocity));
progressInfo.put("totalTime", String.valueOf(totalTime));
progressInfo.put("timeLeft", String.valueOf(timeLeft));
progressInfo.put("length", String.valueOf(length));
progressInfo.put("totalLength", String.valueOf(totalLength));
}
return super.execute();
}
@Override
public void setSession(Map<String, Object> session) {
// TODO Auto-generated method stub
this.session=session;
}
public Map<String, String> getProgressInfo() {
return progressInfo;
}
/*public UploadStatus getStatus() {
return status;
}*/
}
package video.action;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
import javax.servlet.ServletContext;
import org.apache.commons.io.FileUtils;
import org.apache.struts2.ServletActionContext;
import org.apache.struts2.interceptor.SessionAware;
import video.dao.UploadDao;
import video.daoimpl.UploadDaoImpl;
import videomodel.VideoInfo;
import cn.history.pojo.User;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
public class UploadFile extends ActionSupport{
private static final long serialVersionUID = 4182168930616232826L;
private String name; //標(biāo)題名
private File video;
private String videoFileName;
private String videoContentType;
private String videoDesc; //描述
private int cate; //類型
private String tag; //標(biāo)簽
/*private VideoInfo videoInfo=new VideoInfo();*/
private String msg;
private UploadDao uploadDao=new UploadDaoImpl();
public String upload() throws Exception{
//完成上傳
ServletContext sc=ServletActionContext.getServletContext();
String directory=sc.getRealPath("/video");//得到存放文件的真是目錄
//根據(jù)視頻的不同類型,存放在不同的目錄下
if(cate==1){ //如果是傳統(tǒng)文學(xué)
directory=directory+"/guoxue";
}else if(cate==2){
directory=directory+"/minjian";
}else{
directory=directory+"/jiari";
}
SimpleDateFormat sdf=new SimpleDateFormat("yyyyMMddHHmmssS");//格式化時(shí)間輸出
String Rname=null;
if(name!=null&&!name.equals("")){
Rname=name+"_"+sdf.format(new Date())+".mp4";
}else{
Rname=videoFileName;
}
System.out.println(Rname);
//構(gòu)建目標(biāo)文件
File target=new File(directory,Rname);
FileUtils.copyFile(video, target);
System.out.println(Rname+"\n"+videoFileName+"\n"+videoDesc+"\n"+videoContentType);
//將成功上傳的視頻基本信息保存至數(shù)據(jù)庫(kù)m
String filePath=target.getPath();
filePath=filePath.substring(filePath.indexOf("video")).replace("\\", "/");
System.out.println(filePath);
VideoInfo videoInfo=new VideoInfo();
videoInfo.setVideoName(Rname);
videoInfo.setVideoDesc(videoDesc);
videoInfo.setVideoUrl(filePath);
videoInfo.setCate(cate);
videoInfo.setTag(tag);
//ActionContext.getContext().getSession().get("name");
if(ActionContext.getContext().getSession().get("user")!=null){
User user=(User) ActionContext.getContext().getSession().get("user");
videoInfo.setAuthorId(user.getUser_id());
}else{
//設(shè)置為管理員的id,默認(rèn)是管理員上傳的
videoInfo.setAuthorId(1);
}
int tag=uploadDao.saveVideo(videoInfo);
if(tag==0){
msg="上傳失敗(存儲(chǔ)數(shù)據(jù)庫(kù)過(guò)程出錯(cuò))";
return INPUT;
}else{
msg="視頻上傳成功";
}
return SUCCESS;
}
/* public VideoInfo getVideoInfo() {
return videoInfo;
}
public void setVideoInfo(VideoInfo videoInfo) {
this.videoInfo = videoInfo;
}*/
/*public String getName() {
return name;
}*/
public void setName(String name) {
this.name = name;
}
// public File getVideo() {
// return video;
// }
public void setVideo(File video) {
System.out.println(video);
this.video = video;
}
// public String getVideoDesc() {
// return videoDesc;
// }
public void setVideoDesc(String videoDesc) {
this.videoDesc = videoDesc;
}
/*public int getCate() {
return cate;
}*/
public void setCate(int cate) {
this.cate = cate;
}
/*public String getTag() {
return tag;
}*/
public void setTag(String tag) {
this.tag = tag;
}
// public String getVideoFileName() {
// return videoFileName;
// }
public void setVideoFileName(String videoFileName) {
this.videoFileName = videoFileName;
}
/*public String getVideoContentType() {
return videoContentType;
}*/
public void setVideoContentType(String videoContentType) {
this.videoContentType = videoContentType;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
MybatisPlus多表連接查詢的問(wèn)題及解決方案
MybatisPlus官方并沒(méi)有提供多表連接查詢的通用解決方案,然而連接查詢是相當(dāng)普遍的需求,今天通過(guò)本文給大家介紹下MybatisPlus多表連接查詢的問(wèn)題及解決方案,感興趣的朋友一起看看吧2022-01-01
SpringBoot啟動(dòng)失敗的解決方法:A component required a&nb
這篇文章主要介紹了解決SpringBoot啟動(dòng)失?。篈 component required a bean of type ‘xxxxxxx‘ that could not be found.,目前解決方法有兩種,一種是不注入bean的方式,另一種是使用@Component的方式,本文給大家詳細(xì)講解,需要的朋友可以參考下2023-02-02
Java 8實(shí)現(xiàn)任意參數(shù)的單鏈表
這篇文章主要為大家詳細(xì)介紹了Java 8實(shí)現(xiàn)任意參數(shù)的單鏈表,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-10-10
Mybatis 插入一條或批量插入 返回帶有自增長(zhǎng)主鍵記錄的實(shí)例
下面小編就為大家分享一篇Mybatis 插入一條或批量插入 返回帶有自增長(zhǎng)主鍵記錄的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2017-12-12
Spring Boot 2.0多數(shù)據(jù)源配置方法實(shí)例詳解
這篇文章主要介紹了Spring Boot 2.0多數(shù)據(jù)源配置方法實(shí)例詳解,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2018-09-09
MyBatis批量插入(insert)數(shù)據(jù)操作
本文給大家分享MyBatis批量插入(insert)數(shù)據(jù)操作知識(shí),非常不錯(cuò),具有參考借鑒價(jià)值,感興趣的朋友一起學(xué)習(xí)吧2016-06-06

