天天看点

struts2上传文件显示进度条实例---有图有代码,一看就会

2018-03-09 修改

js其实是单线程的程序,因此在调用计时器的时候会先把setInterval或者settimeout函数之外的代码全部执行完才开始进入计时器程序…..好吧,这些是经典的面试题….

啰嗦两句:显示进度条其实没那么困难

有时候,不知道是环境问题还是人品问题,遇到的bug总是莫名其妙的。可是说到底还是某个知识点不太熟练。这次吐槽一下前端jquery的submit方法。下午的时候测试提交能顺利完成任务,可是到了十一点多的时候就不行了。我知道,程序员十大谎言之一就是:我真的没改这部分代码。好吧,既然不太清除bug到底是怎么出现的,那么就换一种提交方法吧。

所以直接把button类型改成submit,再设置它的click事件,让表单自己提交好了。知识点的盲区就在这时候出现了。由于要轮询后台文件的上传进度信息,不得不一边提交file一遍ajax获取进度。实在是不太清楚setinterval这个方法是异步还是同步,会不会阻塞submit(又和上一段中提到的文件submit不成功混在一起,就测试了好久)。在这个地方也停留了好久。。。

最后,项目还残存的问题就是:明明是每隔500ms向后台请求的进度信息,但是实际上后台并不能够在这段时间内返回对应的信息。亟待优化!

效果图如下:

struts2上传文件显示进度条实例---有图有代码,一看就会
获取文件上传信息的基本步骤:经测试有效

上传文件时如何获取上传进度信息?

从网上查一下资料就可以知道struts2对文件上传的request请求做了封装,也就是说在调用上传文件的action时就已经上传temp完成了。

那么既然这样,我们就可以重写struts2封装request的类:org.apache.struts2.dispatcher.multipart.JakartaMultiPartRequest;

由于这个类的许多方法都是private的,那么也就是说我们是无法通过extends来重写父类的一些方法的。怎么办呢?

暴力一点!

直接自定义一个JakartaMultiPartRequest类型的类,把父类的方法全部copy过来,然后在struts.xml中配置:

<struts>
    <bean type="org.apache.struts2.dispatcher.multipart.MultiPartRequest"
          name="myRequestParser" class="listener.MultiPartRequest"
          scope="default" optional="true" />
    <!-- 注意struts2.3.15.1以前版本这里为struts.multipart.handler, struts2.3.15.1(包含2.3.15.1)这里为struts.multipart.parser-->
    <constant name="struts.multipart.handler" value="myRequestParser"/>
    <!--action-->
    ....
    </struts>
           

接下来我们实现上述配置文件中的MultiPartRequest类:

通过intellij的反编译插件,我们decode JakartaMultiPartRequest这个类:源码如下—-大量代码来袭,直接copy这部分吧 不用细看

/*
 * $Id: JakartaMultiPartRequest.java 1384107 2012-09-12 20:14:23Z lukaszlenart $
 *
 * 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.struts2.dispatcher.multipart;

import com.opensymphony.xwork2.LocaleProvider;
import com.opensymphony.xwork2.inject.Inject;
import com.opensymphony.xwork2.util.LocalizedTextUtil;
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.FileUploadBase;
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.Locale;
import java.util.Map;
import java.util.Set;

/**
 * Multipart form data request adapter for Jakarta Commons Fileupload package.
 */
public class JakartaMultiPartRequest implements MultiPartRequest {

    static final Logger LOG = LoggerFactory.getLogger(JakartaMultiPartRequest.class);

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

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

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

    protected long maxSize;
    private Locale defaultLocale = Locale.ENGLISH;

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

    @Inject
    public void setLocaleProvider(LocaleProvider provider) {
        defaultLocale = provider.getLocale();
    }

    /**
     * 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 void setLocale(HttpServletRequest request) {
        if (defaultLocale == null) {
            defaultLocale = request.getLocale();
        }
    }

    protected String buildErrorMessage(Throwable e, Object[] args) {
        String errorKey = "struts.messages.upload.error." + e.getClass().getSimpleName();
        if (LOG.isDebugEnabled()) {
            LOG.debug("Preparing error message for key: [#0]", errorKey);
        }
        return LocalizedTextUtil.findText(this.getClass(), errorKey, defaultLocale, e.getMessage(), args);
    }

    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) {
        if (LOG.isDebugEnabled()) {
            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() < ) {
            LOG.debug("No file has been uploaded for the field: " + item.getFieldName());
            return;
        }

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

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

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

        // 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);
        item.delete();
    }

    private List<FileItem> parseRequest(HttpServletRequest servletRequest, String saveDir) throws FileUploadException {
        DiskFileItemFactory fac = createDiskFileItemFactory(saveDir);
        ServletFileUpload upload = new ServletFileUpload(fac);
        upload.setSizeMax(maxSize);
        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();
        if (saveDir != null) {
            fac.setRepository(new File(saveDir));
        }
        return fac;
    }

    /* (non-Javadoc)
     * @see org.apache.struts2.dispatcher.multipart.MultiPartRequest#getFileParameterNames()
     */
    public Enumeration<String> 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<FileItem> items = files.get(fieldName);

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

        List<String> contentTypes = new ArrayList<String>(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<FileItem> items = files.get(fieldName);

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

        List<File> fileList = new ArrayList<File>(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<FileItem> items = files.get(fieldName);

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

        List<String> fileNames = new ArrayList<String>(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<FileItem> items = files.get(fieldName);

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

        List<String> fileNames = new ArrayList<String>(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<String> v = params.get(name);
        if (v != null && v.size() > ) {
            return v.get();
        }

        return null;
    }

    /* (non-Javadoc)
     * @see org.apache.struts2.dispatcher.multipart.MultiPartRequest#getParameterNames()
     */
    public Enumeration<String> 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<String> v = params.get(name);
        if (v != null && v.size() > ) {
            return v.toArray(new String[v.size()]);
        }

        return null;
    }

    /* (non-Javadoc)
     * @see org.apache.struts2.dispatcher.multipart.MultiPartRequest#getErrors()
     */
    public List<String> 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 != - && forwardSlash > backwardSlash) {
            filename = filename.substring(forwardSlash + , filename.length());
        } else if (backwardSlash != - && backwardSlash >= forwardSlash) {
            filename = filename.substring(backwardSlash + , 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();
            }
        };
    }

    /* (non-Javadoc)
    * @see org.apache.struts2.dispatcher.multipart.MultiPartRequest#cleanUp()
    */
    public void cleanUp() {
        Set<String> names = files.keySet();
        for (String name : names) {
            List<FileItem> items = files.get(name);
            for (FileItem item : items) {
                if (LOG.isDebugEnabled()) {
                    String msg = LocalizedTextUtil.findText(this.getClass(), "struts.messages.removing.file",
                            Locale.ENGLISH, "no.message.found", new Object[]{name, item});
                    LOG.debug(msg);
                }
                if (!item.isInMemory()) {
                    item.delete();
                }
            }
        }
    }

}
           

好的,我们把上面这部分代码copy到我们自定义的public class MultiPartRequest extends JakartaMultiPartRequest {}中

复制粘贴完了之后,我们要ctrl f找到parseRequest方法。在这里,我们要设置文件上传进度监听器

/**
     * 自定义的parseRequest方法
     * @param servletRequest
     * @param saveDir
     * @return
     * @throws FileUploadException
     */
    private List<FileItem> parseRequest(HttpServletRequest servletRequest, String saveDir) throws FileUploadException {
        System.out.println("调用parseRequest方法");
        UploadProgressListener listener = new UploadProgressListener(servletRequest);
        DiskFileItemFactory fac = createDiskFileItemFactory(saveDir);
        ServletFileUpload upload = new ServletFileUpload(fac);
        upload.setSizeMax(maxSize);
        upload.setProgressListener(listener);
        System.out.println("设置监听器成功");
        return upload.parseRequest(createRequestContext(servletRequest));
    }
           

在上面这个代码片段中可以看到:我们new了一个监听器UploadProgressListener 的实例,然后调用了ServletFileUpload .setProgressListener(listener)方法。也就是说:这里的监听器与我们以前写过的request,session等等监听器不同,不需要在web.xml中配置。这里只需要一行代码即可解决。

那么我们就来实现这个监听器吧!

这个监听器需要实org.apache.commons.fileupload.ProgressListener这个接口:我们直接implement一下。

在update方法中我们可以获取到已上传的文件长度,上传的文件的总长度,当前上传第几个文件。(当你上传一个文件的时候,打印日志就会发现这里会输出2。个人猜测是先上传到temp然后再上传到指定路径…)

我们在update方法中设置了文件上传状态实体类的实例,并且保存到session。这一步就是能让前端使用ajax访问到文件当前的上传进度信息。

package listener;

import entity.FileUploadProgress;
import org.apache.commons.fileupload.ProgressListener;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

/**
 * Created by zipple on 2017/10/13.
 * 监听文件上传情况
 * 实现org.apache.commons.fileupload.ProgressListener接口
 */
public class UploadProgressListener implements ProgressListener {
    private HttpSession session;//创建监听器实例的时候获取session

    //在自定义的MultiPartRequest 类中 创建此监听器的实例
    public UploadProgressListener(HttpServletRequest request) {
        session = request.getSession();
        FileUploadProgress fileUploadProgress = new FileUploadProgress();
        fileUploadProgress.setFlag(false);
        session.setAttribute("fileUploadProgress", fileUploadProgress);
    }
    @Override
    public void update(long readBytes, long totalBytes, int currentItem) {
        //实现文件上传的核心方法
        Object attribute = session.getAttribute("fileUploadProgress");
//        System.out.println("当前已读取:"+readBytes+" 总长度:"+totalBytes+" 正在保存:"+currentItem);
        FileUploadProgress fileUploadProgress;
        if(null == attribute){
            fileUploadProgress = new FileUploadProgress();
            fileUploadProgress.setFlag(false);
            System.out.println("uploadListener文件上传的开始时间:"+fileUploadProgress.getStartTime());
            session.setAttribute("fileUploadProgress", fileUploadProgress);
        }else{
            fileUploadProgress = (FileUploadProgress)attribute;
        }
        fileUploadProgress.setCurrentLength(readBytes);
        fileUploadProgress.setTotalLength(totalBytes);
        if(readBytes==totalBytes){
            fileUploadProgress.setFlag(true);
        }else{
            fileUploadProgress.setFlag(false);
        }
        session.setAttribute("fileUploadProgress", fileUploadProgress);
    }
}
           

文件上传状态实体类代码:

package entity;

/**
 * Created by zipple on 2017/10/14.
 * 上传文件进度信息实体类
 */
public class FileUploadProgress {
    private long startTime = System.currentTimeMillis();//开始时间
    private long totalLength=;//文件上传的总长度
    private long currentLength=;//当前文件上传的长度
    private boolean flag;//是否上传完成

    public long getTotalLength() {
        return totalLength;
    }

    public void setTotalLength(long totalLength) {
        this.totalLength = totalLength;
    }

    public long getCurrentLength() {
        return currentLength;
    }

    public void setCurrentLength(long currentLength) {
        this.currentLength = currentLength;
    }

    public boolean isFlag() {
        return flag;
    }

    public void setFlag(boolean flag) {
        this.flag = flag;
    }

    public long getStartTime() {
        return startTime;
    }

    public void setStartTime(long startTime) {
        this.startTime = startTime;
    }

    public FileUploadProgress(){
        super();
    }
}
           

前端获取后台文件上传的进度信息

好的,前面已经做完了所有的基本工作了。万事俱备,我们最后只需要实现对应的查询action即可。在这个地方我也要记录一个bug。在使用ajax访问这个action的时候,一直报错。当然,我在前面的博客中也吐槽过了,这个报错信息一点用没有。我又找了好久。后来发现jsonData只是单纯的定义了map对象,并没有new出它的实例,所以空指针异常了!!!

这里我们使用的是返回json数据。(需要struts2-json-plugin-2.3.16.jar)

package action;

import com.opensymphony.xwork2.Action;
import entity.FileUploadProgress;
import org.apache.struts2.ServletActionContext;
import util.DataUtil;

import java.util.HashMap;
import java.util.Map;

/**
 * Created by zipple on 2017/10/15.
 * 获取文件进度信息
 */
public class ProgressAction implements Action {
    private Map<String,Object> jsonData;
    @Override
    public String execute() throws Exception {
        System.out.println("获取上传文件进度信息");
        jsonData = new HashMap<>();//初始化jsonData!!!!
        FileUploadProgress p;
        Object attribute = ServletActionContext.getRequest().getSession().getAttribute("fileUploadProgress");
        if(null == attribute){
            System.out.println("session中没有fileupload信息");
            jsonData.put("completed", false);
            jsonData.put("isStarted", false);
            setJsonData(jsonData);
            return SUCCESS;
        }else{
            System.out.println("session中有fileupload信息");
            p = (FileUploadProgress)attribute;
        }

        System.out.println("action中获取到的文件上传的开始时间:"+p.getStartTime());
        System.out.println("action运行到这里的时间:"+System.currentTimeMillis());
        long time = (System.currentTimeMillis() - p.getStartTime())/  + ; //已传输的时间 单位:s

        System.out.println("截至目前上传时间:"+time);

        double v = ((double)p.getCurrentLength()) / (double)time; // b/s
        System.out.println("传输速度:"+v);
        System.out.println("pAction:当前上传--"+p.getCurrentLength());

        jsonData.put("percent", DataUtil.percent(p.getCurrentLength(),p.getTotalLength()));
        jsonData.put("remain", (int)(p.getTotalLength()/v-time));
        jsonData.put("isStarted", true);
        jsonData.put("completed", p.isFlag());
        if (p.isFlag()){
            System.out.println("已完成,重置fileUploadProgress");
            ServletActionContext.getRequest().getSession().removeAttribute("fileUploadProgress");
        }
        setJsonData(jsonData);
        return SUCCESS;
    }

    public Map<String,Object> getJsonData() {
        return jsonData;
    }

    public void setJsonData(Map<String,Object> jsonData) {
        this.jsonData = jsonData;
    }
}
           

返回json数据的struts.xml配置如下:

<package name="json" extends="struts-default,json-default">
        <action name="getProgress" class="action.ProgressAction" method="execute">
            <result name="success" type="json">
                <param name="root">jsonData</param><!-- action中的要返回的属性 -->
            </result>
        </action>
        </package>
           

项目做到这里,后端的事情已经做完了。接下来就是前端显示进度条的事情。需要的同学可以继续往下看咯。

前端那些事儿——css实现进度条控件

css:可以直接copy,无需细看(firefox下测试无问题)

.progress{
    height: px;
    background: #ebebeb;
    border-left: px solid transparent;
    border-right: px solid transparent;
    border-radius: px;
}

.progress .blue {
    background: #5aaadb;
    border-color: #459fd6 #3094d2 #277db2;
    background-image: -webkit-linear-gradient(top, #aed5ed %, #bbbe2 %, #aaadb %);
    background-image: -moz-linear-gradient(top, #aed5ed %, #bbbe2 %, #aaadb %);
    background-image: -o-linear-gradient(top, #aed5ed %, #bbbe2 %, #aaadb %);
    background-image: linear-gradient(to bottom, #aed5ed %, #bbbe2 %, #aaadb %);
}

.progress > span {
    position: relative;
    float: left;
    margin:  -px;
    min-width: px;
    height: px;
    line-height: px;
    text-align: right;
    background: #cccccc;
    border: px solid;
    border-color: #bfbfbf #b3b3b3 #9e9e9e;
    border-radius: px;
    background-image: -webkit-linear-gradient(top, #f0f0f0 %, #dbdbdb %, #cccccc %);
    background-image: -moz-linear-gradient(top, #f0f0f0 %, #dbdbdb %, #cccccc %);
    background-image: -o-linear-gradient(top, #f0f0f0 %, #dbdbdb %, #cccccc %);
    background-image: linear-gradient(to bottom, #f0f0f0 %, #dbdbdb %, #cccccc %);
    -webkit-box-shadow: inset  px rgba(, , , ),  px px rgba(, , , );
    box-shadow: inset  px rgba(, , , ),  px px rgba(, , , );
}
.progress > span > span {
    padding:  px;
    font-size: px;
    font-weight: bold;
    color: #404040;
    color: rgba(, , , );
    text-shadow:  px rgba(, , , );
}
.progress > span:before {
    content: '';
    position: absolute;
    top: ;
    bottom: ;
    left: ;
    right: ;
    z-index: ;
    height: px;
    background: url("http://js.itivy.com/5-progress-bars/img/progress.png")   repeat-x;
    border-radius: px;
}
           

html调用progress代码很简单,就一行:这里设置隐藏,上传文件时再显示

控制进度条代码:在提交文件时同步调用此计时器即可。

setInterval(progressBar,);

    /**
      * 展示上传进度条
      */
function progressBar () {
         console.log("询问后台进度...");
         $.ajax({
             type : "GET",  //提交方式
             url : "getProgress.action",//路径
             success : function(result) {//返回数据根据结果进行相应的处理
                 console.log(result);
                 console.log("文件是否上传完成"+result.completed);
                 if (result.isStarted){
                     if (result.completed){
                         $(".progress").hide();
                         clearInterval(progressBar);//清除计时器
                     }else{
                         $(".progress >span").css({"width":result.percent});
                         $(".progress >span>span").text(result.percent);
                         $(".remain").text(result.remain);
                     }
                 }else{
                     console.log("文件还没有提交");
                 }
             },
             //异常处理
             error:function (XMLHttpRequest, textStatus, errorThrown) {
                 console.log(XMLHttpRequest+"---"+textStatus+"---"+errorThrown);
             }
         });

      }
           

看到这里,上传文件显示进度条的相关内容基本上是结束了。

有问题的,可以留言交流~

生活有许多的不如意,如果一不开心,就寄希望于“如果当初”,那你永远都不会开心。