© 版权声明:本文为博主原创文章,转载请注明出处
说明:
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=" 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=" 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.效果预览