【Java web】Servlet+bootstrap-fileinput实现文件上传功能

本文记录了如何使用bootstrap-fileinput插件和servlet实现一个酷酷的文件上传功能。

预览

在这里插入图片描述

介绍

bootstrap-fileinput是什么?
bootstrap-fileinput是一款非常优秀的HTML5文件上传插件,支持bootstrap 3.x 和4.x版本,具有非常多的特性:多文件选择。这个插件能最简单的帮你完成文件上传功能,且使用bootstrap样式。还支持多种文件的预览,images, text, html, video, audio, flash。另外还支持ajax方式上传文件,可以看到上传进度。支持拖拽的方式添加和删除文件。
如何下载?
在它的官网可以找到手动安装的选项,点击下载压缩包。下载的压缩包中包含了核心的CSS和JS文件,拷贝到你的工程下即可使用。注意,这个插件依赖于JQuery,所以在网页中应当先引入JQuery。
在这里插入图片描述
具体其他使用方式可参考官网,因为这个插件有很多扩展功能,比如说切换form表单提交或者Ajax提交,单个文件或多个文件上传,文件上传完成后执行哪个回调函数等等,官网已经写得很详细了,这里主要介绍使用Servlet作为服务端如何接受插件上传的文件。

HTML代码

注意:要使用bootstrap-fileinput插件,我们需要先将插件对应的CSS文件以及JS文件放在目录下,这样才能在HTML中被引用。

HTML代码如下:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Upload Image上传头像</title>

<!-- 加载Bootstrap的核心CSS文件 -->
<link href="./css/bootstrap.min.css" rel="stylesheet">
<link href="./css/fileinput.css" rel="stylesheet">

<!-- 加载cdn上的JQuery文件 -->
<script src="https://cdn.bootcss.com/jquery/1.12.4/jquery.min.js"></script>
<!--如果没有正常从网络上加载jquery的话,就加载本地jquery-->
<script>window.jQuery|| document.write('<script src="./js/vendor/jquery.min.js"><\/script>')</script>

<!-- 加载本地bootstrap核心js文件-->
<script src="./js/bootstrap.min.js"></script>

<!-- 加载本地bootstrap-fileinput核心js文件,注意文件加载顺序-->
<script src="./js/plugins/piexif.js"></script>
<script src="./js/plugins/sortable.js"></script>
<script src="./js/plugins/purify.js"></script>
<script src="./js/fileinput.js"></script>
<script src="./js/locales/zh.js"></script>

</head>
<body>
	<div class="container">
		<div class="row">
			<div class=" col-sm-12 col-lg-12 col-md-12 ">
				<div class="file-loading">
					<input id="input-705" name="kartik-input-705" type="file" accept="image/*" multiple>
				</div>
			</div>
		</div>
	</div>

	<script>
		//当网页加载完成后执行以下函数,实现对插件的初始化设置
		$(document).ready(function() {
				$("#input-705").fileinput({
					//设置允许上传文件的后缀
					allowedFileExtensions : ['jpg', 'png' ],
					//设置语言为中文
					language : "zh",
					//上传服务的URL,这个URL简写也可以,写完整的URL也可以
					//使用简写的话,在Ajax提交时会在前部加上当前所在的域(域=协议+ip+端口号),以组成完整的URL
					uploadUrl : "/你的项目名称/UploadImageServlet",
					//选择异步上传
					uploadAsync : true,
					//设置一次上传允许的最多文件数量
					minFileCount : 1,
					//设置一次上传允许的最少文件数量
					maxFileCount : 1,
					overwriteInitial : false,
					initialPreviewAsData : true,
					//设置enctype属性,默认为application/x-www-form-urlencode,但是这种属性不支持上传二进制文件,所以诞生了multipart/form-data
					enctype : "multipart/form-data",
				});
			});
	</script>
</body>
</html>

Servlet代码

有趣的一点是,当你选择一次上传多张图像时,bootstrap-fileinput插件会为每个文件发送一个Ajax请求,所以我们在写Servlet的时候只需要对一个文件进行处理即可。
例子,我们一次上传两张图像时:
在这里插入图片描述
按F12打开Network,点击上传按钮,可以看到向Servlet发送了两次请求:
在这里插入图片描述
具体代码如下:

package servlet;

import java.io.IOException;
import java.io.File;
import java.io.PrintWriter;

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 java.util.List;

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

/**
 * Servlet implementation class UploadImageServlet
 */
@WebServlet("/UploadImageServlet")
public class UploadImageServlet extends HttpServlet {
	  	private static final long serialVersionUID = 1L;
	     
	    // 上传文件存储目录
	    private static final String UPLOAD_DIRECTORY = "image";
	 
	    // 上传配置
	    private static final int MEMORY_THRESHOLD   = 1024 * 1024 * 3;  // 3MB
	    private static final int MAX_FILE_SIZE      = 1024 * 1024 * 40; // 40MB
	    private static final int MAX_REQUEST_SIZE   = 1024 * 1024 * 50; // 50MB
	    
	    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
			doPost(request, response);
		}
	    
	    /**
	     * 上传数据及保存文件
	     */
	    protected void doPost(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
	        //如果没有匹配到对应sessionId的session,则返回null
	    	HttpSession session=request.getSession(false);
	        
	    	// 检测是否为multipart/form-data上传
	        if (!ServletFileUpload.isMultipartContent(request)) {
	            // 如果不是则停止
	            PrintWriter writer = response.getWriter();
	            writer.println("Error: 表单必须包含 enctype=multipart/form-data");
	            writer.flush();
	            return;
	        }
	    	
	    	
	        // 配置上传参数
	        DiskFileItemFactory factory = new DiskFileItemFactory();
	        // 设置内存临界值 - 超过后将产生临时文件并存储于临时目录中
	        factory.setSizeThreshold(MEMORY_THRESHOLD);
	        // 设置临时存储目录
	        factory.setRepository(new File(System.getProperty("java.io.tmpdir")));
	 
	        ServletFileUpload upload = new ServletFileUpload(factory);
	         
	        // 设置最大文件大小上传值
	        upload.setFileSizeMax(MAX_FILE_SIZE);
	         
	        // 设置最大请求值 (包含文件和表单数据)
	        upload.setSizeMax(MAX_REQUEST_SIZE);

	        // 中文处理
	        upload.setHeaderEncoding("UTF-8"); 

	        // 构造路径来存储上传的文件,这个路径相对当前应用的目录
	        String uploadPath = request.getServletContext().getRealPath("./") + UPLOAD_DIRECTORY;
	        
	        // 如果目录不存在则创建
	        File uploadDir = new File(uploadPath);
	        if (!uploadDir.exists()) {
	            uploadDir.mkdir();
	        }
	        
	        try {
	            // 解析请求的内容提取文件数据
	            @SuppressWarnings("unchecked")
	            List<FileItem> formItems = upload.parseRequest(request);
	            if (formItems != null && formItems.size() > 0) {
	                // 迭代表单数据
	                for (FileItem item : formItems) {
	                    // 使用item.isFormField()方法判断FileItem类对象封装的数据是否为普通文本表单字段,还是文件表单字段
	                    if (!item.isFormField()) {
	                        String fileName = item.getName();	
	                       
	                        String filePath = uploadPath + File.separator + fileName;
	                        File storeFile = new File(filePath);
	                        // 保存文件到硬盘
	                        item.write(storeFile);
	                    }
	                }
	            }
	        } catch (Exception ex) {
	        	ex.printStackTrace();
	            //上传失败
	        	response.setCharacterEncoding("utf-8");
	        	//返回Json字符串
		        String json = "{\"state\":\"0:failed\"}";
		        response.getWriter().write(json);
		        return ;
	        }
	        // 上传成功
	        response.setCharacterEncoding("utf-8");
	        //返回Json字符串
	        String json = "{\"state\":\"1:success\"}";
	        response.getWriter().write(json);
	        return ;
	    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值