© 版权声明:本文为博主原创文章,转载请注明出处

说明:

  1. 使用commons-fileupload.jar实现文件上传及进度监听

  2. 使用bootstrap的进度条进行页面显示

  3. 因为进度数据保存在session中,所以同一个浏览器同时只能发送一次上传请求,多次发送进度会错乱

实例:

1.项目结构

2.pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

  	<modelVersion>4.0.0</modelVersion>

	<groupId>org.file</groupId>
	<artifactId>process</artifactId>
	<packaging>war</packaging>
	<version>0.0.1-SNAPSHOT</version>

	<dependencies>
		<!-- Junit -->
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.12</version>
			<scope>test</scope>
		</dependency>
		<!-- Servlet -->
		<dependency>
		    <groupId>javax.servlet</groupId>
		    <artifactId>javax.servlet-api</artifactId>
		    <version>3.1.0</version>
		    <scope>provided</scope>
		</dependency>
		<!-- Commons-fileupload -->
		<dependency>
		    <groupId>commons-fileupload</groupId>
		    <artifactId>commons-fileupload</artifactId>
		    <version>1.3.2</version>
		</dependency>
	</dependencies>

	<build>
		<finalName>process</finalName>
	</build>

</project>

3.index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Excel上传</title>
<link rel="stylesheet" type="text/css" href="bootstrap/bootstrap.min.css">
</head>
<body>
	<div class="container" align="center">
		<form action="uploadExcel" method="post" enctype="multipart/form-data">
			<table class="table" style="width: 50%">
				<tr id="msg" style="display: none;">
					<th colspan="2" style="text-align: center;">
						<font color="#00CD00">文件上传成功,共用时${time }ms</font>
					</th>
				</tr>
				<tr>
					<th>上传文件1:</th>
					<td><input type="file" name="file"/></td>
				</tr>
				<tr>
					<th>上传文件2:</th>
					<td><input type="file" name="file"/></td>
				</tr>
				<tr>
					<th>上传人:</th>
					<td><input type="text" name="user"/></td>
				</tr>
				<tr>
					<th> </th>
					<td>
						<button id="submit" type="submit" class="btn btn-default">上传</button>
					</td>
				</tr>
			</table>
		</form>
	</div>
	<!-- 文件上传模态框 -->
	<div id="progressModal" class="modal fade" tabindex="-1" role="dialog" data-backdrop="static"
		data-keyboard="false">
  		<div class="modal-dialog" role="document">
    		<div class="modal-content">
				<div class="modal-header">
			  		<h4 class="modal-title">文件上传进度</h4>
				</div>
      			<div class="modal-body">
        			<div id="progress" class="progress">
						<div id="progress_rate" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100"
							class="progress-bar progress-bar-success progress-bar-striped active"
							role="progressbar" style="width: 0%">
	  							<span id="percent">0%</span>
						</div>
					</div>
      			</div>
    		</div>
  		</div>
	</div>
	<script type="text/javascript" src="bootstrap/jquery-3.2.0.min.js"></script>
    <script type="text/javascript" src="bootstrap/bootstrap.min.js"></script>
    <script type="text/javascript">

    	var process;// 定时对象

    	$(function() {

    		var time = "${time}";
    		if (time != null && time != "") {
    			$("#msg").css("display", "block");
    		}

    		$("#submit").bind("click", function(){

    			process = setInterval("getProcess()", 100);// 每0.1s读取一次进度
        		$("#progressModal").modal("show");// 打开模态框

        	});

    	});

    	// 读取文件上传进度并通过进度条展示
    	function getProcess() {

    		$.ajax({
    			type: "get",
    			url: "uploadExcel",
    			success: function(data) {
    				var rate = data * 100;
    				rate = rate.toFixed(2);
    				$("#progress_rate").css("width", rate + "%");
    				$("#percent").text(rate + "%");
    				if (rate >= 100) {
    					clearInterval(process);
    					$("#percent").text("文件上传成功!");
    				}
    			}
    		});

    	}

    </script>
</body>
</html>

4.UploadProcess.java

package org.file.upload;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.math.BigDecimal;
import java.util.Calendar;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.ProgressListener;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

@WebServlet("/uploadExcel")
public class UploadProcess extends HttpServlet {

	private static final long serialVersionUID = 1L;

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

		System.out.println("开始上传文件...");

		// 使用session保存进度数据
		final HttpSession session = req.getSession();

		long start_time = Calendar.getInstance().getTimeInMillis();
		// 获取上传文件临时保存路径
		String tempPath = this.getServletContext().getRealPath("/WEB-INF/upload");

		File file = new File(tempPath);
		if (!file.exists() && !file.isDirectory()) {// 目录不存在或不是一个目录
			file.mkdirs();
		}

		try {
			// 创建DiskFileItemFactory工厂类
			DiskFileItemFactory factory = new  DiskFileItemFactory();

			// 创建一个文件上传解析器
			ServletFileUpload upload = new ServletFileUpload(factory);
			// 监听文件上传进度
			upload.setProgressListener(new ProgressListener() {

				public void update(long pBytesRead, long pContentLength, int pItems) {

					session.setAttribute("fileSize", pContentLength);
					session.setAttribute("loadSize", pBytesRead);

				}
			});
			// 解决上传文件的中文乱码
			upload.setHeaderEncoding("UTF-8");

			if (!ServletFileUpload.isMultipartContent(req)) {// 普通表单
				return ;
			} else {
				// 利用文件上传解析器解析数据并存放到list中
				List<FileItem> list = upload.parseRequest(req);
				// 循环所有数据
				for (FileItem item: list) {
					// 判断数据来源
					if (item.isFormField()) {//普通输入框中的数据
						String name = item.getFieldName();// 输入框的name值
						String value = item.getString("UTF-8"); // 输入框的值
						System.out.println(name + " : " + value);
					} else {//文件
						// 获取上传文件的文件路径(不同浏览器不同,有的是文件名,有的是全路径)
						String fileName = item.getName();
						if (fileName == null || "".equals(fileName.trim())) {
							continue;
						}
						// 获取文件名
						fileName = fileName.substring(fileName.lastIndexOf("\\") + 1);
						// 获取上传文件的输入流
						InputStream is = item.getInputStream();
						// 创建一个文件输出流
						FileOutputStream fos = new FileOutputStream(tempPath + "\\" + fileName);
						// 创建一个缓存区
						byte[] buff = new byte[1024];

						int len = 0;
						while ((len = is.read(buff)) > 0) {// 循环读取数据
							fos.write(buff, 0, len);// 使用文件输出流将缓存区的数据写入到指定的目录中
						}
						// 关闭输出流
						fos.close();
						// 关闭输入流
						is.close();
						// 删除临时文件
						item.delete();
					}
				}
			}
			long end_time = Calendar.getInstance().getTimeInMillis();
			long lt = end_time - start_time;
			System.out.println("文件上传成功,共用时" + (end_time - start_time) + "ms");
			req.setAttribute("time", lt);
			req.getRequestDispatcher("index.jsp").forward(req, resp);
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

		// 获取进度数据
		HttpSession session = req.getSession();
		Object obj1 = session.getAttribute("loadSize");
		long loadSize = 0L;
		if (obj1 != null) {
			loadSize = Long.valueOf(obj1.toString());
		}
		Object obj2 = session.getAttribute("fileSize");
		long fileSize = 1L;
		if (obj2 != null) {
			fileSize = Long.valueOf(obj2.toString());
		}

		// 计算上传比例
		double rate = loadSize * 1.0 / fileSize;
		BigDecimal bd = new BigDecimal(rate);
		rate = bd.setScale(4, BigDecimal.ROUND_HALF_UP).doubleValue();

		// 返回
		resp.setContentType("text/html;charset=UTF-8");
		PrintWriter pw = resp.getWriter();
		pw.write(rate + "");
		pw.flush();
		pw.close();

	}

}

5.效果预览

利用Bootstrap简单实现一个文件上传进度条的更多相关文章

  1. HTML5矢量实现文件上传进度条

    在HTML中,在文件上传的过程中,很多情况都是没有任何的提示,这在体验上很不好,用户都不知道到时有没有在上传.上传成功了没有,所以今天给大家介绍的内容是通过HT for Web矢量来实现HTML5文件 ...

  2. 基于HT for Web矢量实现HTML5文件上传进度条

    在HTML中,在文件上传的过程中,很多情况都是没有任何的提示,这在体验上很不好,用户都不知道到时有没有在上传.上传成功了没有,所以今天给大家介绍的内容是通过HT for Web矢量来实现HTML5文件 ...

  3. iOS_文件上传进度条的实现思路-AFNettworking

    iOS_文件上传进度条的实现思路-AFNettworking //要上传的文件名,在这里我使用当前日期做为文件的名称 NSString * fileName =[NSString stringWith ...

  4. PHP中使用Session配合Javascript实现文件上传进度条功能

    Web应用中常需要提供文件上传的功能.典型的场景包括用户头像上传.相册图片上传等.当需要上传的文件比较大的时候,提供一个显示上传进度的进度条就很有必要了. 在PHP .4以前,实现这样的进度条并不容易 ...

  5. asp.net文件上传进度条研究

    文章:asp.net 文件上传进度条实现代码

  6. layui文件上传进度条(模拟)

    1.修改上传组件js(没测) https://blog.csdn.net/weixin_42457316/article/details/81017471 https://www.cnblogs.co ...

  7. js 文件上传进度条

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  8. 基于jquery ajax的多文件上传进度条

    效果图 前端代码,基于jquery <!DOCTYPE html> <html> <head> <title>主页</title> < ...

  9. 基于HTML5 Ajax文件上传进度条如何实现(jquery版本)

    <!DOCTYPE html> <html> <head> <title>html5_2.html</title> <meta htt ...

随机推荐

  1. fullpage.js小技巧

    创造一个自适应的section: 在 section 类旁边加上类 fp-auto-height 例如:<div class="section fp-auto-height" ...

  2. 完美扫描PHP特殊一句话后门

    <?php /********************** 作者 Spider 网上公布的各种PHP后门全军覆没 针对一些特殊变形的后门需要自己添加特征 误报率不到百分之一 ********** ...

  3. iOS多线程编程之Grand Central Dispatch(GCD)介绍和使用

    http://blog.csdn.net/totogo2010/article/details/8016129 GCD很好的博文

  4. Caused by: java.lang.NoSuchMethodError: org.slf4j.impl.StaticLoggerBinder.getSingleton()Lorg/slf4j/i

    Caused by: java.lang.NoSuchMethodError: org.slf4j.impl.StaticLoggerBinder.getSingleton()Lorg/slf4j/i ...

  5. Using Post_Query Trigger in Oracle Forms

    When a query is open in the block, the Post-Query trigger fires each time Form Builder fetches a rec ...

  6. JAVA基础总结一:

    一.数据类型及变量名和注释 1. Java 中的数据类型分为两大类: 1) 原生数据类型 (Primitive Data Type) :8个(byte.char.short.int.long.floa ...

  7. JS初学之-代码精简思路

    1.差不多的代码,观察其不一样的地方,使用变量存起来,方便替代. 2.将其存入函数之中方便调用.

  8. z-index兼容问题:关于ie6/7下的z-index

    z-index这个属性其实在挺多地方都会用到,在百度上搜索也有大量关于z-index的篇幅去阐述这个属性,特别是在ie6下的z-index处理有更多的相关文章,本文就不再围绕z-index这一属性的基 ...

  9. matplotlib入门--1(条形图, 直方图, 盒须图, 饼图)

    作图首先要进行数据的输入,matplotlib包只提供作图相关功能,本身并没有数据读入.输出函数,针对各种试验或统计文本数据输入可以使用numpy提供的数据输入函数. # -*- coding: gb ...

  10. 在windows上缓存git 密码

    缓存git密码 一搜索 大部分都是在linux上的 . git config --global credential.helper cache 但在windows上pull或者push会报如下错误: ...