struts2文件上传带进度条(一)
2015-06-01 22:40
330 查看
实现功能的思路: 1,得到文件上传的进度 2,在页面上显示上传的进度,这就需要不断去读取文件上传的进度 在实现这个功能的时候,首先要认识到,struts2是怎么处理上传的文件的,
struts2也用到了它,那么,到底该怎么找到是哪个类对文件上传进行处理呢?
首先想到的是在配置文件里面找到拦截文件上传的类,在struts2默认的配置文件里,
<bean type="org.apache.struts2.dispatcher.multipart.MultiPartRequest" name="jakarta" class="org.apache.struts2.dispatcher.multipart.JakartaMultiPartRequest" scope="default"/> <bean type="org.apache.struts2.dispatcher.multipart.MultiPartRequest" name="jakarta-stream" class="org.apache.struts2.dispatcher.multipart.JakartaStreamMultiPartRequest" scope="default"/> ``` ![这是文件上传处理类的位置](http://img.blog.csdn.net/20150601221652534) ![这是引入Apache的上传的插件,从这里可以大概知道调用了什么方法](http://img.blog.csdn.net/20150601221820279) 我们要得到上传的进度条,就需要知道文件上传的监测是在哪个类执行的,初步看了一下,执行文件上传的操作,是在parse这个方法里进行的一些操作,代码如下:
这里写代码片
* Creates a new request wrapper to handle multi-part data using methods adapted from Jason Pell's * multipart classes (see class description). * * @param saveDir the directory to save off the file * @param request the request containing the multipart * @throws java.io.IOException is thrown if encoding fails. */ public void parse(HttpServletRequest request, String saveDir) throws IOException { try { setLocale(request); **processUpload(request, saveDir);** } catch (FileUploadBase.SizeLimitExceededException e) { if (LOG.isWarnEnabled()) { LOG.warn("Request exceeded size limit!", e); } String errorMessage = buildErrorMessage(e, new Object[]{e.getPermittedSize(), e.getActualSize()}); if (!errors.contains(errorMessage)) { errors.add(errorMessage); } } catch (Exception e) { if (LOG.isWarnEnabled()) { LOG.warn("Unable to parse request", e); } String errorMessage = buildErrorMessage(e, new Object[]{}); if (!errors.contains(errorMessage)) { errors.add(errorMessage); } } }
protected List parseRequest(HttpServletRequest servletRequest, String saveDir) throws FileUploadException {
DiskFileItemFactory fac = createDiskFileItemFactory(saveDir);
ServletFileUpload upload = createServletFileUpload(fac);
return upload.parseRequest(createRequestContext(servletRequest));
}
加粗的部分跟进去 ![发现它是继承FileUpload的](https://img-blog.csdn.net/20150602170626349) 然后再跟进去看,仔细一看,还是没有找到类似于监听文件上传的,然后再找其父类FileUploadBase 当然,这个因为是commons FileUpload的代码,所以还得自己下相应的包,这样才能看到源码
/**
* The progress listener.
*/
private ProgressListener listener;
// ----------------------------------------------------- Property accessors
然后在175行找到这个代码,再跟进去
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the “License”); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an “AS IS” BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.fileupload;
/**
* The {@link ProgressListener} may be used to display a progress bar
* or do stuff like that.
*
* @version Id:ProgressListener.java14546912013−03−0912:15:54Zsimonetripodi
*/
public interface ProgressListener {
/** * 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, ...) */ void update(long pBytesRead, long pContentLength, int pItems);
}
仔细看这个说明,已经很明显了,这个就是监听文件上传进度的方法, Apache的命名一般很规范,既然是找监听文件的方法, 那肯定是带有Listen的关键字,所以,在找到这个方法以后, 就可以改写它,让它为我们服务。 现在,就来写自己的监听类了:
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); } } }
}
这样,我们就得到了文件上传的进度,并把它放到session当中, 但是,我们得调用它才可以,因为struts2中是没有使用它的, 所以,我们还得把struts2中对文件上传的类进行改写, 我是直接继承,然后覆盖其中对文件上传处理的类JakartaMultiPartRequest
public class JakartaMultiPartRequestEx extends JakartaMultiPartRequest {
@Override protected List<FileItem> parseRequest(HttpServletRequest servletRequest, String saveDir) throws FileUploadException { DiskFileItemFactory fac = createDiskFileItemFactory(save a8ea Dir); ServletFileUpload upload = createServletFileUpload(fac); **upload.setProgressListener(new FileUploadProgress(servletRequest));** return upload.parseRequest(createRequestContext(servletRequest)); }
}
加粗的部分,就是添加文件上传的监听, 这样,就能够得到文件上传的进度了。 然后就是修改struts配置文件中默认的文件上传处理的类了。
完成了这些,就基本完成了一半多了,下面再来说一下 只要实现SessionAware这个接口,然后用session去获取就可以了, 但页面怎么接收呢?怎么从action中传到jsp页面当中。 在这里,我用的是json,就是action中把上传的进度 ![这里写图片描述](https://img-blog.csdn.net/20150602172906263) 然后改一下struts2的配置文件, 在这个插件中,默认是继承struts-default这个包的, 所以,这样并不会影响其他的。 配置文件代码如下:
<interceptor-ref name="fileUpload"> <param name="maximumSize">209715200</param> <!-- <param name="allowedTypes">image/jpeg,image/gif</param> --> </interceptor-ref> <interceptor-ref name="defaultStack"></interceptor-ref> <result name="input">upload.jsp</result> <result>upload.jsp</result> </action> <action name="uploadprogress" class="com.jxnuss.net.x3516.actions.FileUploadProgressAction"> <result type="json"> <param name="root">percent</param>
其中,逻辑名为uploadprogress的action, 是去获取action中的进度的,action的代码如下:
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; } @Override public String execute() throws Exception { percent=(int) session.get("pre"); return SUCCESS; }
}
页面上应该怎么显示出来呢?用进度条的样式,我做的比较简单, 就是通过两个盒子,然后通过宽度的变化来显示进度 ,因为可以通过jquery来动态改变盒子的宽度嘛。 脚本代码如下:
//通过ajax请求upload_progress.action获得上传进度[1,2,3,...,100]
(function(){("#bar").width("0px");
("#upload").click(function(){
//提交表单("form").submit();
//通过代码请求http://localhost:8080/FileUpload/upload_progress.action
//定时执行以下代码
window.setInterval(function(){
var url="uploadprogress.action";
.get(url,function(result){
//响应成功时执行该函数更新进度条("#bar").width(result+"px");
//alert(result);
/* var url="upload_progress.action";
.get(url,function(result){
//响应成功时执行该函数更新进度条("#bar").width(result);
*/
});
}, 100);
});
});
“`
页面代码如下:
加粗部分就是用来显示进度的,到这里就完成了,样式什么的可以用jquery UI来美化,挺不错的
相关文章推荐
- JavaBean与Map相互转化
- 再回首,Java温故知新(六):Java基础之变量
- java中String类常量池分析及"equals"和"==”异同
- java 原型模式
- 像写SQL一样编写Java数据应用-TinySqlDsl
- 新人一枚(spring mvc)
- [Java5新特性]类加载器
- java中的方法重写
- [Java5新特性]类加载器
- Java程序数据库连接,数据源配置,数据库连接池
- Java ClassLoader 原理详细分析
- java学习之JDK5.0特性
- eclipse的快捷键
- Java实现百度贴吧自动签到器
- java静态方法的重写,为什么不能?
- Eclipse汉化
- Spring使用教程(二)配置factorybean
- Java设计模式——Singleton(单例)模式
- struts2中拦截器与过滤器的区别
- Mybatis使用之SpringMVC整合