您的位置:首页 > Web前端 > BootStrap

基于SpringMVC+Bootstrap实现图片异步上传进度显示

2016-10-28 22:08 806 查看

前言

最近在做一个小项目,框架使用现在主流的:SpringMVC(4.1)+Spring(4.1)+MyBatis,前端采用基于Bootstrap封装的模板AdminLTE(2.3.6)。需要实现图片异步上传,了解SpringMVC的文件上传功能是在commons-fileupload组件提供的功能上面做了一些封装来实现,使文件上传开发更容易方便。代码越写越少了,很方便。

这里主要是实现了文件异步上传,后台将文件相对路径返回到页面,显示出来,功能比较简单。本文假设已经将SSM框架配置完毕。

效果

1、打开图片上传Modal



2、选择文件,点击上传,显示进度



3、上传完后,关闭Modal,显示上传图片



实现

实现带进度条的文件上传一般都是服务器端计算文件上传进度,客户端轮询读取显示的方式。

Commons-fileupload组件自带了文件上传进度的监听器,类FileUploadBase提供了它的set方法。

SpringMVC没有实现监听器,所以如果要监听的话得自己扩展CommonsMultipartResolver类,加入代码设置自己实现的监听器

ProgressListener是一个接口,我们需要自己实现它的update方法,参数pBytesRead表示已经上传到服务器的字节数,pContentLength表示所有文件的总大小,pItems表示第几个文件

1、实现ProgressListener

FileUploadProgressListener实现ProgressListener,将上传进度保存到session中。

使用注解

@Component
public class FileUploadProgressListener implements ProgressListener {

private HttpSession session;

@Override
public void update(long bytesRead, long contentLength, int items) {
//设置上传进度
ProgressBean progress = new ProgressBean(bytesRead, contentLength, items);
//将上传进度保存到session中
session.setAttribute("progress", progress);
}

public void setSession(HttpSession session){
this.session = session;
}
}


2、实现MultipartResolver

CustomMultipartResolver继承CommonsMultipartResolver,需要在每一次上传请求中设定处理上传进度的监听器,并处理文件上传。

将第一步中FileUploadProgressListener注入进来

public class CustomMultipartResolver extends CommonsMultipartResolver {

//FileUploadProgressListener 自动注入
@Resource
private FileUploadProgressListener progressListener;

@Override
public MultipartParsingResult parseRequest(HttpServletRequest request) throws MultipartException {
String encoding = determineEncoding(request);
FileUpload fileUpload = prepareFileUpload(encoding);

//FileUploadProgressListener中注入session
progressListener.setSession(request.getSession());

fileUpload.setProgressListener(progressListener);

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、Progress 实体类

public class ProgressBean {

private long bytesRead;

private long contentLength;

private long items;

public ProgressBean(long bytesRead, long contentLength, long items) {
super();
this.bytesRead = bytesRead;
this.contentLength = contentLength;
this.items = items;
}

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 long getItems() {
return items;
}

public void setItems(long items) {
this.items = items;
}

@Override
public String toString() {
return "ProgressBean [bytesRead=" + bytesRead + ", contentLength="
+ contentLength + ", items=" + items + "]";
}

}


4、SpringMVC Controller方法

/**
* 异步上传处理
* @param request
* @param response
* @param file
* @return 返回上传文件相对路径及名称
* @throws IOException
*/
@RequestMapping(value="/file/upload", produces = "text/json;charset=UTF-8")
@ResponseBody
public String uploadFileHandler(HttpServletRequest request, @RequestParam("file") MultipartFile file){

//上传文件每日单独保存
String path = "/upload/"+DateUtil.getNowDate()+"/";

if (file.getSize() > 0) {
//获取绝对路径
String uploadPath = request.getSession().getServletContext().getRealPath(path);
try {
//创建目标文件
File targetFile = new File(uploadPath, file.getOriginalFilename());
if (!targetFile.exists()) {
targetFile.mkdirs();
}

file.transferTo(targetFile);
JSON.toJSONString(path+file.getOriginalFilename());
} catch (Exception e) {

}
}
return null;
}


5、配置CustomMultipartResolver

在SpringMVC配置文件中配置CustomMultipartResolver,支持文件上传

<!-- 支持上传文件 -->
<bean id="multipartResolver" class="com.lead.sy.web.upload.CustomMultipartResolver"/>


6、上传页面

定义上传Modal

<!-- Modal -->
<div id="uploadModal" class="modal fade" role="dialog" aria-labelledby="myModalLabel">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
</div>
<div class="modal-body">
<div class="form-group" id="passwordDiv">
<label>选择营业执照照片</label>
<input class="form-control" type="file" id="uploadFile">
</div>
<div class="form-group">
<input id="btnUpload" type="submit" name="submit" class="btn btn-success" value="上传" />
</div>
</div>
</div>
</div>
</div>


上传控制JS代码

<script>
$(function () {
// 默认上传按钮不可用
$("#btnUpload").attr("disabled", true);

// 弹出上传Model
$("#activeUpload").click(function(){
$("#uploadModal").modal("show");
})

// 上传按钮点击事件
$("#btnUpload").click(function() {
//上传按钮修改为可用
$(this).attr("disabled", true);
uploadFunction();
})

// 文件修改时
$("#uploadFile").change(function() {
$("#btnUpload").val("上传");
var file = $(this).prop("files");
if (file.length != 0) {
$("#btnUpload").attr("disabled", false);
}
});

//文件上传
function uploadFunction() {
var uploadFile = $("#uploadFile").get(0).files[0]; //获取文件对象

// FormData 对象
var form = new FormData();
form.append("file", uploadFile); // 文件对象
var uploadUrl = "<%=path%>/file/upload";//异步上传地址
$.ajax({
cache: false,
type: "POST",
url: uploadUrl,
contentType: false,
processData: false,
data: form,
xhr: function(){ //获取ajaxSettings中的xhr对象,为它的upload属性绑定progress事件的处理函数
myXhr = $.ajaxSettings.xhr();
if(progressFunction && myXhr.upload) { //检查进度函数和upload属性是否存在
//绑定progress事件的回调函数
myXhr.upload.addEventListener("progress",progressFunction, false);
}
return myXhr; //xhr对象返回给jQuery使用
},
error: function(request) {
alert("Connection error");
},
success: function(data) {
$("input[name=companyLicenseImg]").val(data);
$("#licenseImg").attr("src","<%=path%>"+data); //将后台返回图片路径设置给IMG,显示图片
$("#licenseImg").attr("width","100");
$("#activeUpload").val("重新上传");

$("#btnUpload").attr("disabled", false);
$("#btnUpload").val("上传");
$("#uploadModal").modal("hide");
}
});
}

//进度条控制
function progressFunction(evt) {
if (evt.lengthComputable) {
var completePercent = Math.round(evt.loaded / evt.total * 100)+ "%";
$("#btnUpload").val("正在上传,进度:" + completePercent);
}
}
});
</script>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: