资讯专栏INFORMATION COLUMN

Structs下上传文件进度显示

Charlie_Jade / 782人阅读

摘要:两种思路,一种是使用插件,使用插件就比较简单,进度在前端实现,记录发送的文件大小并提供函数。另一种就是在后台监听接收数据,前台使用轮回实时读取展示进度信息。环境前台上传插件,后台。

两种思路,一种是使用plupload插件,使用插件就比较简单,进度在前端实现,plupload记录发送的文件大小并提供函数。具体可参考http://www.plupload.com/官网。

另一种就是在后台监听接收数据,前台使用ajax轮回实时读取展示进度信息。

本文旨在叙述第二种方法后台方法。

环境:前台上传插件http://www.jq22.com/jquery-in...,后台Structs。(注插件提供了springmvc版本的进度显示)

1、定义返回信息实体类

public class UploadStatus {
    private long bytesRead;//已读数据
    private long contentLength;//文件总数据
    private long items;//第几个文件
    private long startTime = System.currentTimeMillis();//开始时间
    private long useTime = System.currentTimeMillis();//已用时间
    private int percent;//完成百分比
    
    public long getBytesRead() {
        return bytesRead;
    }
    public void setBytesRead(long bytesRead) {
        this.bytesRead = bytesRead;
    }
    public long getContentLength() {
        return contentLength;
    }
    public void setContentLength(long contentLength) {
        this.contentLength = contentLength;
    }
    public long getItems() {
        return items;
    }
    public void setItems(long items) {
        this.items = items;
    }
    public long getStartTime() {
        return startTime;
    }
    public void setStartTime(long startTime) {
        this.startTime = startTime;
    }
    public long getUseTime() {
        return useTime;
    }
    public void setUseTime(long useTime) {
        this.useTime = useTime;
    }
    public int getPercent() {
        return percent;
    }
    public void setPercent(int percent) {
        this.percent = percent;
    }
    @Override
    public String toString() {
        // TODO Auto-generated method stub
        return "UploadStatus [percent=" + percent + ", items=" + items + "]";
    }
}

2、创建监听类实现ProgressListener

import javax.servlet.http.HttpSession;

import org.apache.commons.fileupload.ProgressListener;

public class UploadListener implements ProgressListener{
    private HttpSession session;
    public UploadListener(HttpSession session){
        super();
        this.session = session;
        UploadStatus uploadStatus = new UploadStatus();
        session.setAttribute("upload_status", uploadStatus);
    }
    
    @Override
    public void update(long bytesRead, long contentLength, int items) {
        // TODO Auto-generated method stub
        UploadStatus uploadStatus = (UploadStatus) session.getAttribute("upload_status");
        uploadStatus.setBytesRead(bytesRead);
        uploadStatus.setContentLength(contentLength);
        uploadStatus.setItems(items);
        uploadStatus.setUseTime(System.currentTimeMillis()-uploadStatus.getStartTime());
        uploadStatus.setPercent((int)(100*bytesRead/contentLength));
        session.setAttribute("upload_status", uploadStatus);
        
    }
    
}

3、实现MultiPartRequest接口,主要是让自己的监听事件监听上传

package com.cngrain.util;

import com.opensymphony.xwork2.inject.Inject;
import com.opensymphony.xwork2.util.logging.Logger;
import com.opensymphony.xwork2.util.logging.LoggerFactory;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.RequestContext;
import org.apache.commons.fileupload.disk.DiskFileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.struts2.StrutsConstants;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.struts2.dispatcher.multipart.MultiPartRequest;

public class UploadCommonsMultipartResolver implements MultiPartRequest {
    static final Logger LOG = LoggerFactory.getLogger(MultiPartRequest.class);

    // maps parameter name -> List of FileItem objects
    protected Map> files = new HashMap>();

    // maps parameter name -> List of param values
    protected Map> params = new HashMap>();

    // any errors while processing this request
    protected List errors = new ArrayList();

    protected long maxSize;

    @Inject(StrutsConstants.STRUTS_MULTIPART_MAXSIZE)
    public void setMaxSize(String maxSize) {
        this.maxSize = Long.parseLong(maxSize);
    }

    /**
     * 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 {
            processUpload(request, saveDir);
        } catch (FileUploadException e) {
            LOG.warn("Unable to parse request", e);
            errors.add(e.getMessage());
        }
    }

    private void processUpload(HttpServletRequest request, String saveDir)
            throws FileUploadException, UnsupportedEncodingException {
        for (FileItem item : parseRequest(request, saveDir)) {
            if (LOG.isDebugEnabled()) {
                LOG.debug("Found item " + item.getFieldName());
            }
            if (item.isFormField()) {
                processNormalFormField(item, request.getCharacterEncoding());
            } else {
                processFileField(item);
            }
        }
    }

    private void processFileField(FileItem item) {
        LOG.debug("Item is a file upload");

        // Skip file uploads that don"t have a file name - meaning that no file
        // was selected.
        if (item.getName() == null || item.getName().trim().length() < 1) {
            LOG.debug("No file has been uploaded for the field: " + item.getFieldName());
            return;
        }

        List values;
        if (files.get(item.getFieldName()) != null) {
            values = files.get(item.getFieldName());
        } else {
            values = new ArrayList();
        }

        values.add(item);
        files.put(item.getFieldName(), values);
    }

    private void processNormalFormField(FileItem item, String charset) throws UnsupportedEncodingException {
        LOG.debug("Item is a normal form field");
        List values;
        if (params.get(item.getFieldName()) != null) {
            values = params.get(item.getFieldName());
        } else {
            values = new ArrayList();
        }

        // note: see http://jira.opensymphony.com/browse/WW-633
        // basically, in some cases the charset may be null, so
        // we"re just going to try to "other" method (no idea if this
        // will work)
        if (charset != null) {
            values.add(item.getString(charset));
        } else {
            values.add(item.getString());
        }
        params.put(item.getFieldName(), values);
    }

    private List parseRequest(HttpServletRequest servletRequest, String saveDir) throws FileUploadException {
        DiskFileItemFactory fac = createDiskFileItemFactory(saveDir);
        ServletFileUpload upload = new ServletFileUpload(fac);
        upload.setSizeMax(maxSize);
        /* 自己新建监听器 */
        UploadListener progressListener = new UploadListener(servletRequest.getSession());
        upload.setProgressListener(progressListener);// 添加自己的监听器

        return upload.parseRequest(createRequestContext(servletRequest));
    }

    private DiskFileItemFactory createDiskFileItemFactory(String saveDir) {
        DiskFileItemFactory fac = new DiskFileItemFactory();
        // Make sure that the data is written to file
        fac.setSizeThreshold(0);
        if (saveDir != null) {
            fac.setRepository(new File(saveDir));
        }
        return fac;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.apache.struts2.dispatcher.multipart.MultiPartRequest#
     * getFileParameterNames()
     */
    public Enumeration getFileParameterNames() {
        return Collections.enumeration(files.keySet());
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * org.apache.struts2.dispatcher.multipart.MultiPartRequest#getContentType(
     * java.lang.String)
     */
    public String[] getContentType(String fieldName) {
        List items = files.get(fieldName);

        if (items == null) {
            return null;
        }

        List contentTypes = new ArrayList(items.size());
        for (FileItem fileItem : items) {
            contentTypes.add(fileItem.getContentType());
        }

        return contentTypes.toArray(new String[contentTypes.size()]);
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * org.apache.struts2.dispatcher.multipart.MultiPartRequest#getFile(java.
     * lang.String)
     */
    public File[] getFile(String fieldName) {
        List items = files.get(fieldName);

        if (items == null) {
            return null;
        }

        List fileList = new ArrayList(items.size());
        for (FileItem fileItem : items) {
            File storeLocation = ((DiskFileItem) fileItem).getStoreLocation();
            if (fileItem.isInMemory() && storeLocation != null && !storeLocation.exists()) {
                try {
                    storeLocation.createNewFile();
                } catch (IOException e) {
                    if (LOG.isErrorEnabled()) {
                        LOG.error("Cannot write uploaded empty file to disk: " + storeLocation.getAbsolutePath(), e);
                    }
                }
            }
            fileList.add(storeLocation);
        }

        return fileList.toArray(new File[fileList.size()]);
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * org.apache.struts2.dispatcher.multipart.MultiPartRequest#getFileNames(
     * java.lang.String)
     */
    public String[] getFileNames(String fieldName) {
        List items = files.get(fieldName);

        if (items == null) {
            return null;
        }

        List fileNames = new ArrayList(items.size());
        for (FileItem fileItem : items) {
            fileNames.add(getCanonicalName(fileItem.getName()));
        }

        return fileNames.toArray(new String[fileNames.size()]);
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.apache.struts2.dispatcher.multipart.MultiPartRequest#
     * getFilesystemName(java.lang.String)
     */
    public String[] getFilesystemName(String fieldName) {
        List items = files.get(fieldName);

        if (items == null) {
            return null;
        }

        List fileNames = new ArrayList(items.size());
        for (FileItem fileItem : items) {
            fileNames.add(((DiskFileItem) fileItem).getStoreLocation().getName());
        }

        return fileNames.toArray(new String[fileNames.size()]);
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * org.apache.struts2.dispatcher.multipart.MultiPartRequest#getParameter(
     * java.lang.String)
     */
    public String getParameter(String name) {
        List v = params.get(name);
        if (v != null && v.size() > 0) {
            return v.get(0);
        }

        return null;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.apache.struts2.dispatcher.multipart.MultiPartRequest#
     * getParameterNames()
     */
    public Enumeration getParameterNames() {
        return Collections.enumeration(params.keySet());
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.apache.struts2.dispatcher.multipart.MultiPartRequest#
     * getParameterValues(java.lang.String)
     */
    public String[] getParameterValues(String name) {
        List v = params.get(name);
        if (v != null && v.size() > 0) {
            return v.toArray(new String[v.size()]);
        }

        return null;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.apache.struts2.dispatcher.multipart.MultiPartRequest#getErrors()
     */
    public List getErrors() {
        return errors;
    }

    /**
     * Returns the canonical name of the given file.
     * 
     * @param filename
     *            the given file
     * @return the canonical name of the given file
     */
    private String getCanonicalName(String filename) {
        int forwardSlash = filename.lastIndexOf("/");
        int backwardSlash = filename.lastIndexOf("");
        if (forwardSlash != -1 && forwardSlash > backwardSlash) {
            filename = filename.substring(forwardSlash + 1, filename.length());
        } else if (backwardSlash != -1 && backwardSlash >= forwardSlash) {
            filename = filename.substring(backwardSlash + 1, filename.length());
        }

        return filename;
    }

    /**
     * Creates a RequestContext needed by Jakarta Commons Upload.
     * 
     * @param req
     *            the request.
     * @return a new request context.
     */
    private RequestContext createRequestContext(final HttpServletRequest req) {
        return new RequestContext() {
            public String getCharacterEncoding() {
                return req.getCharacterEncoding();
            }

            public String getContentType() {
                return req.getContentType();
            }

            public int getContentLength() {
                return req.getContentLength();
            }

            public InputStream getInputStream() throws IOException {
                InputStream in = req.getInputStream();
                if (in == null) {
                    throw new IOException("Missing content in the request");
                }
                return req.getInputStream();
            }
        };
    }

    @Override
    public void cleanUp() {
        // TODO Auto-generated method stub

    }

}

4、.配置struts.xml





5、编写action获取上传信息

    @Action(value = "getStatus", results = { @Result(name = SUCCESS,  type = "json" ) }) 
    public String getStatus(){
        uploadStatus = (UploadStatus)request.getSession().getAttribute("upload_status");
        return SUCCESS;
    }

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/67809.html

相关文章

  • 【许晓笛】 EOS 智能合约案例解析(3)

    摘要:文件地址智能合约文件由部分组成定义类型的别名各个类型的数据结构智能合约的数据结构体李嘉图条款注格式不支持注释,上面的双斜线大家理解就好。是李嘉图合约,刚刚被加入到智能合约中,官方还没有进一步说明。 详解 EOS 智能合约的 abi 文件 这次向大家介绍 eosio.token 智能合约的最后一个文件 —— abi文件。ABI 全称 Application Binary Interfac...

    philadelphia 评论0 收藏0
  • H5拖放异步文件上传之二——上传进度监听

    摘要:添加功能显示待上传文件列表支持移除待上传文件使用显示上传进度支持中断上传方法返回一个对象,用来表示上传的进度。监听数据传输进行中通过监听这个事件,可获得上传进度。   上一篇《H5拖放+FormData接口+NodeJS,完整异步文件上传(一)》,我们走通了拖放文件上传的整个流程,但离实际使用场景还有差距。这篇,我们来添加几个实际使用场景必要的功能,向实际使用再走一步。 添加功能 显...

    Godtoy 评论0 收藏0
  • H5拖放异步文件上传之二——上传进度监听

    摘要:添加功能显示待上传文件列表支持移除待上传文件使用显示上传进度支持中断上传方法返回一个对象,用来表示上传的进度。监听数据传输进行中通过监听这个事件,可获得上传进度。   上一篇《H5拖放+FormData接口+NodeJS,完整异步文件上传(一)》,我们走通了拖放文件上传的整个流程,但离实际使用场景还有差距。这篇,我们来添加几个实际使用场景必要的功能,向实际使用再走一步。 添加功能 显...

    blankyao 评论0 收藏0
  • TP5整合阿里云OSS上传文件第二节,异步上传头像实现,

    摘要:版本也是我最喜欢的方式这个代码有点黏在一起了凑合看把李昊天创建实例服务器异步接受地址指定选择文件的按钮容器禁止多选不压缩选择之后自动上传防止低版本浏览器用到了只允许选择图片文件。 TP5整合阿里云OSS上传文件第二节,上传头像实现首先先看一个效果图上传失败效果图:showImg(https://segmentfault.com/img/bVbaJLZ?w=983&h=561);上传成功...

    douzifly 评论0 收藏0

发表评论

0条评论

Charlie_Jade

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<