struts2文件异步上传带进度条(二)
2015-06-04 20:04
417 查看
这次写的struts2文件上传带进度条是在(一)的基础上进行的,主要是实现表单的异步提交,这样,就可以很好的交互。因为在实践中,一个表单,除了要上传的文件,还有一些其他的内容,要想让文件先上传,然后再提交表单,这就要让文件先提交,然后再提交后面的。一开始走了一些弯路,用jquery来提交文件,但发现这个时候,页面总是刷新,这个时候,就不能实现预先的功能,于是,我想到了用frameset,但这个还是不太好,太复杂了。后来,我想用两个表单来实现,文件一个表单,文件其他的内容一个表单。但最重要的是,要让文件那个表单提交的时候不要刷新,这样就要用异步提交了,而且有文件的异步提交,我在网上找了很多文章,最后用jquery form js进行了实现。 ![这个是文件以外内容的表单](https://img-blog.csdn.net/20150604193705806) ![这个是文件上传的表单](https://img-blog.csdn.net 4000 /20150604193740891)
<script type="text/javascript" src="${pageContext.request.contextPath }/js/jquery-1.8.2.min.js"></script> <script type="text/javascript" src="${pageContext.request.contextPath }/js/jquery.form.js"></script>
要使用query的form js的插件,还得下载,下载后,然后引入,下载地址如下:http://www.vaikan.com/docs/jquery.form.plugin/jquery.form.plugin.html#sample3 然后,页面异步上传的代码如下:包含了验证的功能,验证文件是否为空,文件的上传类型,文件的大小。
<script type="text/javascript"> $(function(){ <!--点击上传按钮进行文件的异步上传 --> $("#upload").on("click",function(){ <!--判断文件是否为空 --> if($("[name=taskfile]").attr('value')==''){ alert("请选择文件上传!!!"); return; } <!-- jquery验证文件的类型,只允许上传doc,docx,ppt,pdf,xls,txt格式 --> var filepath = $("input[name='taskfile']").val(); var extStart = filepath.lastIndexOf("."); var ext = filepath.substring(extStart, filepath.length).toUpperCase(); if (ext != ".DOC" && ext != ".DOCX" &&ext != ".PPT" && ext != ".PDF" && ext != ".XLS" && ext != ".TXT" ) { alert("文件限于doc,docx,ppt,pdf,xls,txt格式"); return false; } <!--jquery验证文件的大小,大小限制为20M以下 --> var file = $('#taskfile').get(0).files[0]; if (file) { var fileSize = 0; /* if (file.size > 1024 * 1024) fileSize = (Math.round(file.size * 100 / (1024 * 1024)) / 100).toString() + 'MB'; else fileSize = (Math.round(file.size * 100 / 1024) / 100).toString() + 'KB'; */ if (file.size > 1024 * 1024) fileSize = (Math.round(file.size * 100 / (1024 * 1024)) / 100).toString() ; /* else fileSize = (Math.round(file.size * 100 / 1024) / 100).toString() ; */ if(fileSize>20){ alert("请上传小于20M的文件"); return; } } <!--异步提交--> $("#fileForm").ajaxSubmit({ type:'post', url:'set_file.action?tnum='+tnum, success:function(data){ $("#taskfileFileName").attr("value",data); }, }); <!--定时器,周期执行读取文件的上传进度--> var p= window.setInterval(function(){ <!--当文件上传进度为100时,停止定时器的运行--> if($("#process").width()==300){ Window.clearInterval(p); } $.post("upload_process.action",null,function(data){ //响应成功时执行该函数更新进度条 $("#process").width(data*3+"px"); //alert(result); }); }, 10); }); <!--删除上传文件 --> $("#remove").click(function () { if($("[name=taskfile]").attr('value')==''){ alert("你还没有选择文件!!!"); return; } if($("#process").width()==0){ alert("你还没有上传文件!!!"); return; } if($("#process").width()==300){ var taskfileFileName=$("[name=taskfileFileName]").attr('value'); alert(taskfileFileName); $.post("upload_delete.action?taskfileFileName="+taskfileFileName+"&tnum="+tnum,null,function(data){ alert("删除"+data); $("#fileForm")[0].reset(); $("#process").width("0px"); $("#process").hide(); }); } }); <!--提交作业的其他信息表单 --> $("#setTaskSubmit").click(function () { $("#setTaskForm").submit(); }); }); </script> <style type="text/css"> #total{ border:1px solid #F00; width:300px; height:20px } /* 进度条 */ #process{ width:0px; height:20px; background-color: red; display:none; } </style>
struts2的配置文件如下:
<bean type="org.apache.struts2.dispatcher.multipart.MultiPartRequest" name="jakarta_ex" class="com.jxnu.stms.util.JakartaMultiPartRequestEx" scope="default"/> <constant name="struts.multipart.parser" value="jakarta_ex"/> ======================================================= <!-- 上传大小限制为20M,类型限制为PPT,DOC,PDF,TXT,XLS格式 --> <action name="set_task" class="setTaskAction" method="set_task"> <!-- <interceptor-ref name="fileUpload"> <param name="maximumSize">20971520</param> <param name="allowedTypes">application/vnd.ms-powerpoint, application/msword,application/pdf,text/plain,application/vnd.ms-excel</param> </interceptor-ref> <interceptor-ref name="defaultStack"></interceptor-ref> --> <param name="savePath">/teacher/upload</param> <result name="set_task" type="chain">task_list</result> <result name="input">set_task.jsp</result> </action> <action name="set_file" class="setTaskAction" method="set_file"> <param name="savePath">/teacher/upload</param> <result name="set_file" type="json"> <param name="root">taskfileFileName</param> </result> <result name="input">set_task.jsp</result> </action> <!-- 教师临时删除上传的文件 --> <action name="upload_delete" class="setTaskAction" method="delete"> <param name="savePath">/teacher/upload</param> <result name="delete" type="json"> <param name="root">result</param> </result> </action> <!-- 教师上传文件读取进度 --> <action name="upload_process" class="fileUploadProgressAction" method="upload_process"> <result type="json"> <param name="root">percent</param> </result> </action>
在这里,我把 d6bc 原来文件上传的过滤去除了,直接是在客户端进行处理
Java代码如下:
@Controller @Scope("prototype") public class SetTaskAction extends ActionSupport implements ModelDriven<Task>,SessionAware{ private static final long serialVersionUID = 1584704723117564063L; private Task task = new Task(); @Override public Task getModel() { return task; } private int tnum; private int cnum; public int getTnum() { return tnum; } public void setTnum(int tnum) { this.tnum = tnum; } public int getCnum() { return cnum; } public void setCnum(int cnum) { this.cnum = cnum; } private File taskfile; private String taskfileFileName; private String taskfileContentType; public File getTaskfile() { return taskfile; } public void setTaskfile(File taskfile) { this.taskfile = taskfile; } public String getTaskfileFileName() { return taskfileFileName; } public void setTaskfileFileName(String taskfileFileName) { this.taskfileFileName = taskfileFileName; } public String getTaskfileContentType() { return taskfileContentType; } public void setTaskfileContentType(String taskfileContentType) { this.taskfileContentType = taskfileContentType; } public static long getSerialversionuid() { return serialVersionUID; } private TeacherService teacherService; public TeacherService getTeacherService() { return teacherService; } @Resource public void setTeacherService(TeacherService teacherService) { this.teacherService = teacherService; } private String savePath; public String getSavePath() { return savePath; } public void setSavePath(String savePath) { this.savePath = savePath; } private Map<String, Object> session; @Override public void setSession(Map<String, Object> session) { this.session=session; } private String result; public String getResult() { return result; } public void setResult(String result) { this.result = result; } public String set_task() throws IOException{ Course c = new Course(); c.setCnum(cnum); Teacher t = new Teacher(); t.setTnum(tnum); task.setTaskPath(taskfileFileName); task.setCourse(c); task.setTeacher(t); teacherService.setTask(task); return "set_task"; } public String set_file() throws IOException{ String dstPath=ServletActionContext.getServletContext().getRealPath(this.getSavePath()+"/"+tnum+taskfileFileName); File dstFile = new File(dstPath); FileUpload f=new FileUpload(); f.copy(taskfile,dstFile); session.put("taskfileFileName", taskfileFileName); return "set_file"; } public String delete(){ String path=ServletActionContext.getServletContext().getRealPath(this.getSavePath()+"/"+tnum+taskfileFileName); new File(path).delete(); result="成功"; return "delete"; } }
文件上传的进度获取的action:
@Controller @Scope("prototype") public class FileUploadProgressAction extends ActionSupport implements SessionAware{ private static final long serialVersionUID = 7345654599038757564L; private Map<String, Object> session; private int percent; public int getPercent() { return percent; } public void setPercent(int percent) { this.percent = percent; } public Map<String, Object> getSession() { return session; } @Override public void setSession(Map<String, Object> session) { this.session=session; } public String upload_process() throws Exception { percent=(int) session.get("pre"); System.out.println(percent); return SUCCESS; } }
action中的copy方法,即文件的处理:从拷贝到服务器的某个位置
package com.jxnu.stms.util; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; public class FileUpload { private static final int BUFFER_SIZE = 16*1024; public void copy(File src, File dst) throws IOException { InputStream in = null; OutputStream out = null; in = new BufferedInputStream(new FileInputStream(src),BUFFER_SIZE); out = new BufferedOutputStream(new FileOutputStream(dst),BUFFER_SIZE); byte[] buffer = new byte[BUFFER_SIZE]; int len=0; while((len=in.read(buffer))>0){ out.write(buffer, 0, len); } { if(null!= in){ in.close(); } if(null != out){ out.close(); } } } }
自己覆盖的监听的方法:
package com.jxnu.stms.util; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import org.apache.commons.fileupload.ProgressListener; public class FileUploadProgress implements ProgressListener{ @SuppressWarnings("unused") private HttpServletRequest servletRequest; HttpSession session ; public FileUploadProgress(HttpServletRequest servletRequest){ super(); this.servletRequest = servletRequest; session = servletRequest.getSession(); } /** * Updates the listeners status information. * * @param pBytesRead The total number of bytes, which have been read * so far. * @param pContentLength The total number of bytes, which are being * read. May be -1, if this number is unknown. * @param pItems The number of the field, which is currently being * read. (0 = no item so far, 1 = first item is being read, ...) */ public void update(long pBytesRead, long pContentLength, int pItems){ int pre=0; if(pContentLength>-1){ int current=(int) (pBytesRead*100/pContentLength); if(current>pre){ pre=current; session.setAttribute("pre", pre); } } } }
覆盖原来struts2对文件上传的处理:
package com.jxnu.stms.util; import java.util.List; import javax.servlet.http.HttpServletRequest; import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.FileUploadException; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload; import org.apache.struts2.dispatcher.multipart.JakartaMultiPartRequest; public class JakartaMultiPartRequestEx extends JakartaMultiPartRequest { @Override protected List<FileItem> parseRequest(HttpServletRequest servletRequest, String saveDir) throws FileUploadException { DiskFileItemFactory fac = createDiskFileItemFactory(saveDir); ServletFileUpload upload = createServletFileUpload(fac); upload.setProgressListener(new FileUploadProgress(servletRequest)); return upload.parseRequest(createRequestContext(servletRequest)); } }
效果如下图:
相关文章推荐
- Java文本编辑器中遇到的问题详解
- 我的第一次Spring学习
- java中serializable解析及用途
- 20135208 JAVA第三次实验
- [转载]JAVA中this用法小结
- spring_aop
- Java中继承thread类与实现Runnable接口的区别
- java实现接口与继承类的区别
- 深入理解java多态性
- Eclipse 4.4.2 取消空格键代码上屏
- C通过JNI调用JAVA
- Java基础—多线程和多进程
- Spring源码追踪3——AOP机制
- spring security自定义过滤器
- 欢迎使用CSDN-markdown编辑器
- 字典树模板(java)
- Java for LeetCode 141 Linked List Cycle
- 利用java反射重写toString
- Java项目开发环境构建工具 Gradle 使用笔记(简单、基本)
- spring整合activemq发送MQ消息[Topic模式]实例