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

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>
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值