Struts2 Ajax 上传文件,显示进度
大家可能以前用ajax上传文件时,是把form提交到<iframe></iframe>,HTML代码如下:
<form action="uploadAction.action" enctype="multipart/form-data" id="fileform" name="fileform" method="post"
target="upload-target">
<input type="file" value="浏览" name="upload" />
<input type="submit" value="提交"/>
</form>
<iframe id="upload-target"></iframe>
这样不用跳转页面就可以实现文件的上传,Action的代码如下:
public class UploadAction extends ActionSupport {
//上传的文件
private File upload;
//上传文件的类型
private String uploadContentType;
上传文件的文件名
private String uploadFileName;
//getter setter
@Override
public String execute() throws Exception {
System.out.println(upload.length());
FileOutputStream fos = new FileOutputStream(ServletActionContext.getServletContext().getRealPath("/") + uploadFileName);
FileInputStream fis = new FileInputStream(upload);
byte[] buffer = new byte[10240];
int len = 0;
double temp = 0;
int total = fis.available();
while((len = fis.read(buffer)) > 0){
fos.write(buffer, 0, len);
fos.flush();
}
fis.close();
fos.close();
return SUCCESS;
}
这样就可以在一个页面上上传文件了。但怎么显示上传文件的进度呢。一开始我的想法是在Action增加一个perc属性,该属性存放着上传的进度,再增加一个方法,输出perc的值.
private double perc;
public String ajaxGetPerc() throws Exception{
HttpServletResponse response = ServletActionContext.getResponse();
PrintWriter writer = null;
writer = response.getWriter();
writer.println(perc);
writer.flush();
writer.close();
return null;
}
最后试验了一下,发现该方法行不通,能上传文件,使用ajax返回的进度值始终是0;
想想第二种方法,使用线程的方式上传文件,并把进度值保存在session中, 并且要使用两个页面,一个页面负责文件的上传,一个负责显示进度。详细代码如下:
upload.jsp负责文件的上传,是一个很普通的HTML页面
<body>
<h1>文件上传</h1>
<form action="uploadAction.action" enctype="multipart/form-data" id="fileform" name="fileform" method="post"
>
<input type="file" value="浏览" name="upload" />
<input type="submit" value="提交"/>
</form>
</body>
showPerc.jsp使用ajax间隔的查询进度值
<?xml version="1.0" encoding="UTF-8" ?>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<script type="text/javascript" src="<%=path %>/js/jquery-1.3.2.min.js"></script>
<script type="text/javascript">
var xmlHttp ;
function createXMLHttp(){
if(window.ActiveXObject){
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
}
else{
xmlHttp = new XMLHttpRequest() ;
}
}
function ajaxSend(){
createXMLHttp() ;
var url ="<%=path %>/getUploadPerc.action?random=" + Math.random(); ;
xmlHttp.onreadystatechange = handler ;
xmlHttp.open("GET",url,true) ;
//xmlHttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
xmlHttp.send(null) ;
}
function handler(){
if(xmlHttp.readyState == 4) {
if(xmlHttp.status == 200) {
var percent = xmlHttp.responseText ;
document.getElementById('pre').innerHTML = percent;
var t = setTimeout("ajaxSend()",100) ;
if(percent == 100){
alert('上传完成');
clearTimeout(t);
}
}
}
return true;
}
window.onload = function(){
ajaxSend();
}
</script>
<title>文件上传</title>
</head>
<body>
<h1>进度条</h1>
<div id="pre"></div>
</body>
</html>
Action代码
package com.struts.action;
import java.io.*;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionSupport;
public class UploadAction extends ActionSupport {
private String title;
private File upload;
private String uploadContentType;
private String uploadFileName;
private String savePath;
private double perc;
public double getPerc() {
return perc;
}
public void setPerc(double perc) {
this.perc = perc;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public File getUpload() {
return upload;
}
public void setUpload(File upload) {
this.upload = upload;
}
public String getUploadContentType() {
return uploadContentType;
}
public void setUploadContentType(String uploadContentType) {
this.uploadContentType = uploadContentType;
}
public String getUploadFileName() {
return uploadFileName;
}
public void setUploadFileName(String uploadFileName) {
this.uploadFileName = uploadFileName;
}
public String getSavePath() {
return savePath;
}
public void setSavePath(String savePath) {
this.savePath = savePath;
}
@Override
public String execute() throws Exception {
System.out.println(upload.length());
File toFile = new File(ServletActionContext.getServletContext().getRealPath("/") + uploadFileName);
HttpSession session = ServletActionContext.getRequest().getSession();
session.setAttribute("perc", 0);
UploadThread uploadThread = new UploadThread(upload,toFile,session);
Thread thread = new Thread(uploadThread);
thread.start();
return SUCCESS;
}
public String ajaxGetPerc() throws Exception{
HttpSession session = ServletActionContext.getRequest().getSession();
System.out.println("session perc------" + session.getAttribute("perc"));
//ServletActionContext.getResponse().getOutputStream().println((String)session.getAttribute("perc"));
HttpServletResponse response = ServletActionContext.getResponse();
PrintWriter writer = null;
writer = response.getWriter();
int perc = (Integer)session.getAttribute("perc");
writer.println(perc);
writer.flush();
writer.close();
return null;
}
}
/**
*
*
* 因为原本文件上传完才能跳转,故在一个线程中上传文件,加速跳转到showPerc.jsp去显示进度.
*
*/
class UploadThread implements Runnable {
//在当前线程中上传的文件.
private File from ;
//保存到服务器硬盘上的位置.
private File to ;
//HttpSession需要传递过来,直接以ServletActionContext.getRequest.getSession将会抛出NullPointerException.
private HttpSession httpSession;
//构造方法,用来传址.
public UploadThread(File from, File to , HttpSession httpSession) {
this.from = from;
this.to = to;
this.httpSession = httpSession;
}
//线程中处理上传.
@Override
public void run() {
copy(from, to , httpSession);
}
//自己实现的上传方法,因为需要计算进度,所以无法使用IOUtils.copy(InputStream in , OutputStream out)方法了.
/**
* @param from 需要上传的文件.
* @param to 保存到服务器上的位置.
* @param httpSession 得到当前窗口的session.
*/
public void copy(File from, File uploadFile , HttpSession httpSession) {
InputStream fis;
try {
fis = new FileInputStream(from);
OutputStream fos = new FileOutputStream(uploadFile);
byte[] buffer = new byte[10240];
int len = 0;
double temp = 0;
int perc = 0;
int total = fis.available();
while((len = fis.read(buffer)) > 0){
fos.write(buffer, 0, len);
fos.flush();
temp += len;
perc = (int)(temp / total * 100);
//System.out.println(perc + "----------------" + total);
httpSession.setAttribute("perc", perc);
Thread.sleep(200);
}
fis.close();
fos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
struts.xml配置文件
<action name="uploadAction" class="com.struts.action.UploadAction">
<result>/showloadbar.jsp</result>
<result name="input">/upload.jsp</result>
<interceptor-ref name="fileUpload">
<param name="allowedTypes">image/bmp,image/png,image/gif,image/jpeg</param>
<param name="maximumSize">20000000000</param>
</interceptor-ref>
<interceptor-ref name="defaultStack"/>
</action>
<action name="getUploadPerc" class="com.struts.action.UploadAction" method="ajaxGetPerc">
</action>
在这里我设置只能上传图片文件.
可以上传文件,并能显示进度。但这里使用session存取进度值,会加重服务器的负担。各位有什么好的方法可以告诉我。谢谢
分享到:
相关推荐
struts2+jquery+ajax实现了文件的异步上传,的MyEclipse编写的简单项目
struts2多文件上传显示进度 无插件
Struts jquery AJAX 文件上传
struts2 ajax图片上传
struts2 ajax 实现 批量上传文件(按ctr键 多选,并非多个文件选择输入框的),jar包太大删掉了 仅用了struts2 的jar包 加进去即可
struts2上传文件的进度条显示,绝对可用! 所达到效果 1.显示总文件大小 2.显示已上传文件大小 3.显示当前进度(百分比控制) 4.显示剩余上传时间 5.显示当前速度 (本人研究了很久才搞出来的,希望大家指教...
本人自己写的struts2结合jquery实现ajax的源码。
文件上传进度条的简单实现,如果有不当的地方还望批评指出,谢谢!
Struts2与AJAX
ssh2(struts2+spring2.5+hibernate3.3+ajax)带进度条文件上传(封装成标签)
struts2+ajax+jquery异步批量上传超大文件.zip struts2+ajax+jquery异步批量上传超大文件.zip struts2+ajax+jquery异步批量上传超大文件.zip struts2+ajax+jquery异步批量上传超大文件.zip struts2+ajax+jquery异步...
Struts2与Ajax 的实现原理,于Servlet+Ajax原理是一致的,都是通过后台的response.getWriter().print("");把数据传输给前台的。 前台Ajax格式如下(需要导入ajax库,比如:jquery-1.11.3.js) 格式: $(function()...
json struts2 ajax文件上传 input type=file,选择相同文件也提交,里面附带类库,可以直接运行。使用工具, myeclipse
MVC Struts2框架搭建,Jquery Ajax异步数据交互,内涵需要的jar包及ppt讲解
下载JS插件jquery-1.4.2.min.js和 jquery.form.js,在html中引入这两个js文件,通过以上的方式,我们就可以通过页面无刷新,在Struts2中无需要进行页面跳转来进行文件上传!
介绍struts、ajax如何返回json数据 一首先引入Struts和json所需的jar包。 二编写页面 三编写action类 四Struts配置
Struts2+Ajax实现的用户登录 Struts2 Ajax Sprint Hibernate
struts2+ajax+jquery异步批量上传超大文件,单文件最大支持2G,一次文件数量,文件大小都可设置。简单明了。绝对可用,稍微懂点的就可以修改为自己所用。你值得拥有! 我会分享给大家更多更好的东西,希望支持!
在struts2基础上实现的包括单文件、多文件的上传及下载