Struts2和common的fileupload实现文件上传并显示实时进度

来源:互联网 发布:ug创建自己的编程模版 编辑:程序博客网 时间:2024/05/21 08:03

Struts2和common的fileupload实现文件上传并显示实时进度
参考连接http://blog.csdn.net/z69183787/article/details/52536255
基于AJAX的文件上传显示进度条实现参考连接
form表单设置为enctype=”multipart/form-data”,提交表单时:
后端获取参数就不能通过request.getParameter(“name”)来获取,而是通过 以下几种方式:
(1)request.getInputStream()来获取参数,但是这种方式如果有多个文件不太好处理;
(2)可以通过struts2框架的自动封装参数来获取,或者通过fileupload来获取;
1.前端页面代码:页面表单提交不跳转页面是通过隐藏iframe实现的

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%><%    String path = request.getContextPath();    String basePath = request.getScheme() + "://"            + request.getServerName() + ":" + request.getServerPort()            + path + "/";%><!DOCTYPE html><html>    <head>    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">    <title>基于Ajax的上传文件显示进度条</title>     <style>      .prog-border {      height: 15px;      width: 205px;      background: #fff;      border: 1px solid #000;      margin: 0;      padding: 0;      }      .prog-bar {      height: 11px;      margin: 2px;      padding: 0px;      background: #178399;      font-size: 10pt;      }      body{        font-family: Arial, Helvetica, sans-serif;        font-size: 10pt;      }      </style>    <script type="text/javascript">    //创建跨浏览器的XMLHttpRequest对象    var timer;    function startListener(){        var xmlhttp;        try{        //IE 5.0             xmlhttp = new ActiveXObject('Msxm12.XMLHTTP');        }catch(e){            try{            //IE 5.5 及更高版本                xmlhttp = new ActiveXObject('Microsoft.XMLHTTP');            }catch(e){                try{                //其他浏览器                    xmlhttp = new XMLHttpRequest();                }catch(e){}            }        }        var progressStatusText = document.getElementById("progressBar");    //获取上传的状态    xmlhttp.open("get","<%=basePath%>upload/getUploadStatus.action",true);        //此处Header设置非常重要,必须设置Content-type类型,负责会报错误          xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");         xmlhttp.onreadystatechange = function(){            if(xmlhttp.readyState == 4){                if(xmlhttp.status == 200){                    progressStatusText.innerHTML = "";                    progressStatusText.innerHTML = xmlhttp.responseText;                    var temp = xmlhttp.responseText.indexOf("success");                    if (  temp > 0 ){                        window.clearTimeout(timer);                    }else{                        timer = window.setTimeout(startListener,1000);                    }                }            }        }        xmlhttp.send(null);    }    function startUpload(){        timer = window.setTimeout(startListener,1000);        return true;}    function cancelUpload(){        var xmlhttp;        try{            //IE 5.0             xmlhttp = new ActiveXObject('Msxm12.XMLHTTP');        }catch(e){            try{            //IE 5.5 及更高版本                xmlhttp = new ActiveXObject('Microsoft.XMLHTTP');            }catch(e){                try{                //其他浏览器                    xmlhttp = new XMLHttpRequest();                }catch(e){}            }        }        var progressStatusText = document.getElementById("progressBar");        xmlhttp.open("get","<%=basePath%>upload/cancelFileUpload.action",true);         xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");        //xmlhttp.setRequestHeader("Content-type", "multipart/form-data");        xmlhttp.onreadystatechange = function(){            if(xmlhttp.readyState == 4){                if(xmlhttp.status == 200){                progressStatusText.innerHTML = "";                progressStatusText.innerHTML = xmlhttp.responseText;                }            }        }        xmlhttp.send(null);        return false;    }    </script>    </head>    <body>    <div id="controlPanel">        <!-- 这个是隐藏的<iframe>作为表单提交后处理的后台目标            通过表单form的target属性指定该<iframe>将返回信息显示在<iframe>框架中      -->      <!--  -->  <iframe id='target_upload' name='target_upload' src='' style='display: none'></iframe>        <form id="fileUploadForm" name="fileUploadForm" action="<%=basePath%>upload/uploadFile.action"             enctype="multipart/form-data" method="post" onsubmit="return startUpload();" target="target_upload">            名字:<input type="text" name="name"/><br>        文件:<input type="file" name="file" id="file" size="40"/><br>            <input type="submit" name="uploadButton" id="uploadButton" value="开始上传"/>            <input type="button" name="cancelUploadButton" id="cancelUploadButton" value="取消上传" onclick="return cancelUpload();"/><br>        </form>           <div id="progressBar">       </div>      </div></body>    </html> 

2.如果使用strut2框架和fileupload整合,必须配置request解析器,因为fileupload无法解析struts2封装过的request;

<!--使用没有被struts2封装过的request,可以在struts.xml中指定文件上传使用的request解析器  -->    <bean type="org.apache.struts2.dispatcher.multipart.MultiPartRequest" name="myRequestParser" class="com.ming.upload.RequestParseWrapper" scope="default" optional="true" />      <constant name="struts.multipart.handler" value="myRequestParser" /> 
package com.ming.upload;import java.io.IOException;import javax.servlet.http.HttpServletRequest;import org.apache.struts2.dispatcher.multipart.JakartaMultiPartRequest;public class RequestParseWrapper extends JakartaMultiPartRequest{           //这里对parse方法进行了覆盖,使其无法封装request      public void parse(HttpServletRequest servletRequest, String saveDir)throws IOException {       }      }  

3.编写一个上传状态类,将其放入session中,这样前后端可以获取上传状态;

package com.ming.upload;import java.util.*;    public class FileUploadStatus {        //上传总量        private long uploadTotalSize=0;        //读取上传总量        private long readTotalSize=0;        //当前上传文件号        private int currentUploadFileNum=0;        //成功读取上传文件数        private int successUploadFileCount=0;        //状态        private String status="";        //处理起始时间        private long processStartTime=0l;        //处理终止时间        private long processEndTime=0l;        //处理执行时间        private long processRunningTime=0l;        //上传文件URL列表        private List uploadFileUrlList=new ArrayList();        //取消上传        private boolean cancel=false;        //上传base目录        private String baseDir="";        public String getBaseDir() {            return baseDir;        }        public void setBaseDir(String baseDir) {            this.baseDir = baseDir;        }        public boolean getCancel() {            return cancel;        }        public void setCancel(boolean cancel) {            this.cancel = cancel;        }        public List getUploadFileUrlList() {            return uploadFileUrlList;        }        public void setUploadFileUrlList(List uploadFileUrlList) {            this.uploadFileUrlList = uploadFileUrlList;        }        public long getProcessRunningTime() {            return processRunningTime;        }        public void setProcessRunningTime(long processRunningTime) {            this.processRunningTime = processRunningTime;        }        public long getProcessEndTime() {            return processEndTime;        }        public void setProcessEndTime(long processEndTime) {            this.processEndTime = processEndTime;        }        public long getProcessStartTime() {            return processStartTime;        }        public void setProcessStartTime(long processStartTime) {            this.processStartTime = processStartTime;        }        public long getReadTotalSize() {            return readTotalSize;        }        public void setReadTotalSize(long readTotalSize) {            this.readTotalSize = readTotalSize;        }        public int getSuccessUploadFileCount() {            return successUploadFileCount;        }        public void setSuccessUploadFileCount(int successUploadFileCount) {            this.successUploadFileCount = successUploadFileCount;        }        public int getCurrentUploadFileNum() {            return currentUploadFileNum;        }        public void setCurrentUploadFileNum(int currentUploadFileNum) {            this.currentUploadFileNum = currentUploadFileNum;        }        public String getStatus() {            return status;        }        public void setStatus(String status) {            this.status = status;        }        public long getUploadTotalSize() {            return uploadTotalSize;        }        public void setUploadTotalSize(long uploadTotalSize) {            this.uploadTotalSize = uploadTotalSize;        }    }  

4.fileupload工具类ServletFileUpload可以设置一个监听器:
这里写图片描述
自定义监听器: 实现ProgressListener接口,并重写update方法

package com.ming.upload;import javax.servlet.http.HttpSession;    import org.apache.commons.fileupload.ProgressListener;    public class UploadListener implements ProgressListener {        private HttpSession session=null;        public UploadListener (HttpSession session){            this.session=session;        }        /**       * 更新状态       * @param pBytesRead 读取字节总数       * @param pContentLength 数据总长度       * @param pItems 当前正在被读取的field号       */      @Override    public void update(long pBytesRead, long pContentLength, int pItems) {            FileUploadStatus fuploadStatus = UploadStatusUtil.takeOutFileUploadStatusBean(this.session);            fuploadStatus.setUploadTotalSize(pContentLength);        //读取完成            if (pContentLength == -1) {                fuploadStatus.setStatus("完成对" + pItems + "个文件的读取:读取了 " + pBytesRead + "/"  + pContentLength+ " bytes.");                fuploadStatus.setReadTotalSize(pBytesRead);                fuploadStatus.setCurrentUploadFileNum(pItems);                fuploadStatus.setProcessEndTime(System.currentTimeMillis());                fuploadStatus.setProcessRunningTime(fuploadStatus.getProcessEndTime());            }else{//读取过程中                fuploadStatus.setStatus("当前正在处理第" + pItems+"个文件:已经读取了 " + pBytesRead + " / " + pContentLength+ " bytes.");                fuploadStatus.setReadTotalSize(pBytesRead);                fuploadStatus.setCurrentUploadFileNum(pItems);                fuploadStatus.setProcessRunningTime(System.currentTimeMillis());            }            //System.out.println("已经读取:" + pBytesRead);            UploadStatusUtil.storeFileUploadStatusBean(this.session, fuploadStatus);        }    }

UploadStatusUtil工具类:

package com.ming.upload;import javax.servlet.http.HttpSession;public class UploadStatusUtil {    public static final String UPLOAD_STATUS="UPLOAD_STATUS";        public static final String UPLOAD_DIR="/upload";    /**       * 把FileUploadStatus Bean保存到session       * @param request       * @param uploadStatusBean       */        public static void storeFileUploadStatusBean(                HttpSession session,                FileUploadStatus uploadStatusBean){            session.setAttribute(UPLOAD_STATUS,uploadStatusBean);        }     /**       * 从request中取出FileUploadStatus Bean       * @param request       * @return       */        public static FileUploadStatus takeOutFileUploadStatusBean(HttpSession session){            Object obj=session.getAttribute(UploadStatusUtil.UPLOAD_STATUS);            if (obj!=null){                return (FileUploadStatus)obj;        }            else{                return null;          }        }    }

5.编写action类:

package com.ming.upload;import java.io.File;import java.io.IOException;import java.io.UnsupportedEncodingException;import java.util.List;import javax.servlet.ServletException;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;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.ServletActionContext;import org.apache.struts2.interceptor.ServletRequestAware;import org.apache.struts2.interceptor.ServletResponseAware;import com.opensymphony.xwork2.ActionSupport;   public class UploadStatusAction extends ActionSupport implements ServletRequestAware, ServletResponseAware{    static final long serialVersionUID = 1L;    private HttpServletRequest request;    private HttpServletResponse response;    @Override    public void setServletRequest(HttpServletRequest request) {        this.request = request;    }    @Override    public void setServletResponse(HttpServletResponse response) {        this.response = response;    }    /**     *      * @Title: uploadFile    * @Description: TODO(上传文件)    * @return void    返回类型    * @throws ServletException    * @throws IOException     */    public void uploadFile(){        try {            //判断文件类型            boolean isMultipart = ServletFileUpload.isMultipartContent(request);                if (isMultipart) {                //上传文件并记录上传状态到session,并响应信息                DiskFileItemFactory factory = new DiskFileItemFactory();                    //设置内存阀值,超过后写入临时文件                    //factory.setSizeThreshold(10240000*5);                //设置临时文件存储位置                    //factory.setRepository(new File(request.getRealPath("/upload/temp")));                ServletFileUpload upload = new ServletFileUpload(factory);                //设置单个文件的最大上传size                    //upload.setFileSizeMax(10240000*5);                    //设置整个request的最大size                    //upload.setSizeMax(10240000*5);                    //注册监听类                    upload.setProgressListener(new UploadListener(request.getSession()));                //保存初始化后的FileUploadStatus Bean                    UploadStatusUtil.storeFileUploadStatusBean(request.getSession(),initFileUploadStatusBean(request));                    try {                    //注意必须重写strut2的request解析方法,struts2封装的request,fileupload无法正确解析                    List<FileItem> items = upload.parseRequest(request);                    //处理文件上传                        for(int i=0;i<items.size();i++){                           FileItem item = items.get(i);                            //取消上传                            if (UploadStatusUtil.takeOutFileUploadStatusBean(request.getSession()).getCancel()){                                deleteUploadedFile(request);                                break;                            }                            //保存文件                            else if (!item.isFormField() && item.getName().length()>0){                                String fileName=takeOutFileName(item.getName());                            String path = ServletActionContext.getServletContext().getRealPath(                                    UploadStatusUtil.UPLOAD_DIR);                            File uploadedFile = new File(path + File.separator + fileName);                            item.write(uploadedFile);                            //更新上传文件列表                                FileUploadStatus fUploadStatus = UploadStatusUtil.takeOutFileUploadStatusBean(request.getSession());                                if(fUploadStatus != null) {                                fUploadStatus.getUploadFileUrlList().add(fileName);                                UploadStatusUtil.storeFileUploadStatusBean(request.getSession(), fUploadStatus);                            }                            Thread.sleep(500);                            }                        }                    } catch (FileUploadException e) {                        e.printStackTrace();                        uploadExceptionHandle(request,"上传文件时发生错误:"+e.getMessage());                    } catch (Exception e) {                        // TODO Auto-generated catch block                        e.printStackTrace();                        uploadExceptionHandle(request,"保存上传文件时发生错误:"+e.getMessage());                    }                }        } catch (ServletException | IOException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }finally {            //清除session中的上传状态对象            request.getSession().removeAttribute(UploadStatusUtil.UPLOAD_STATUS);        }        }      /**     *     * @Title: getUploadStatus    * @Description: TODO(获取上传状态信息)    * @return void    返回类型     */    public void getUploadStatus(){        try {            request.setCharacterEncoding("UTF-8");            FileUploadStatus fUploadStatus=(FileUploadStatus)request.getSession().getAttribute(UploadStatusUtil.UPLOAD_STATUS);                //计算上传完成的百分比                long percentComplete = (long)Math.floor(((double) fUploadStatus.getReadTotalSize()/(double) fUploadStatus.getUploadTotalSize())*100.0);                System.out.println("com:"+percentComplete);                response.setContentType("text/xml");                response.setCharacterEncoding("UTF-8");                response.setHeader("Cache-Control", "no-cache");                if ( ((long)fUploadStatus.getReadTotalSize() == (long)fUploadStatus.getUploadTotalSize()) || (fUploadStatus.getCancel() == true)){                    response.getWriter().write(fUploadStatus.getStatus().toString()+"success");            }else{                    response.getWriter().write(fUploadStatus.getStatus().toString()+"<div class=\"prog-border\"><div class=\"prog-bar\" style=\"width: "                                        + percentComplete + "%;\"></div></div>");                }        } catch (IOException e) {            e.printStackTrace();        }        }    /**     *     * @Title: cancelFileUpload    * @Description: TODO(取消上传)    * @return void    返回类型    * @return     */    public void cancelFileUpload(){        try {            request.setCharacterEncoding("UTF-8");            FileUploadStatus fUploadStatus=(FileUploadStatus)request.getSession().getAttribute(UploadStatusUtil.UPLOAD_STATUS);                fUploadStatus.setCancel(true);                request.getSession().setAttribute(UploadStatusUtil.UPLOAD_STATUS, fUploadStatus);            //调用获取状态方法            getUploadStatus();        } catch (UnsupportedEncodingException e) {            e.printStackTrace();        } finally {            //清除session中的上传状态对象            request.getSession().removeAttribute(UploadStatusUtil.UPLOAD_STATUS);        }    }      /**       * 从文件路径中取出文件名       * @param filePath       * @return     */        private String takeOutFileName(String filePath){            int pos=filePath.lastIndexOf(File.separator);            if (pos>0){                return filePath.substring(pos+1);            }            else{                return filePath;            }        }        /**       * 删除已经上传的文件       * @param request       */        private void deleteUploadedFile(HttpServletRequest request){            FileUploadStatus fUploadStatus= UploadStatusUtil.takeOutFileUploadStatusBean(request.getSession());            for(int i=0;i<fUploadStatus.getUploadFileUrlList().size();i++){              String path = ServletActionContext.getServletContext().getRealPath(                    UploadStatusUtil.UPLOAD_DIR);            File uploadedFile = new File(path+                        File.separator+fUploadStatus.getUploadFileUrlList().get(i));                uploadedFile.delete();            }            fUploadStatus.getUploadFileUrlList().clear();            fUploadStatus.setStatus("删除已上传的文件");            UploadStatusUtil.storeFileUploadStatusBean(request.getSession(),fUploadStatus);        }        /**       * 上传过程中出错处理       * @param request       * @param errMsg       * @throws IOException        * @throws ServletException        */        private void uploadExceptionHandle(                HttpServletRequest request,                String errMsg) throws ServletException, IOException{            //首先删除已经上传的文件            deleteUploadedFile(request);            FileUploadStatus fUploadStatus=UploadStatusUtil.takeOutFileUploadStatusBean(request.getSession());            fUploadStatus.setStatus(errMsg);            UploadStatusUtil.storeFileUploadStatusBean(request.getSession(),fUploadStatus);        }        /**       * 初始化文件上传状态Bean       * @param request       * @return       */        private FileUploadStatus initFileUploadStatusBean(HttpServletRequest request){            FileUploadStatus fUploadStatus=new FileUploadStatus();            fUploadStatus.setStatus("正在准备处理");            fUploadStatus.setUploadTotalSize(request.getContentLength());            fUploadStatus.setProcessStartTime(System.currentTimeMillis());            fUploadStatus.setBaseDir(request.getContextPath()+UploadStatusUtil.UPLOAD_DIR);            return fUploadStatus;    }    } 

5.配置文件:

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE struts PUBLIC    "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"    "http://struts.apache.org/dtds/struts-2.3.dtd"><struts>    <package name="upload" namespace="/upload" extends="struts-default">        <result-types>            <result-type name="json" class="org.apache.struts2.json.JSONResult"/>        </result-types>        <action name="upload" class="com.ming.upload.UploadAction">        </action>        <action name="ajaxUpload" method="ajaxUpload" class="com.ming.upload.AjaxUploadAction">        </action>        <action name="uploadFile" method="uploadFile" class="com.ming.upload.UploadStatusAction">        </action>        <action name="getUploadStatus" method="getUploadStatus" class="com.ming.upload.UploadStatusAction">        </action>        <action name="cancelFileUpload" method="cancelFileUpload" class="com.ming.upload.UploadStatusAction">        </action>    </package></struts>
原创粉丝点击