AJAX+Servlet3.0实现异步文件上传(单个文件、多个文件上传、带文件的表单提交)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_40348465/article/details/84630275

   一、上传单个文件

     

    1.JSP页面代码

     

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<script type="text/javascript" src="jquery/jquery-3.3.1.js"></script>
<script type="text/javascript" src="bootstrap/bootstrap.js"></script>
<link href="bootstrap/bootstrap.css" rel="stylesheet">
<title>AJAX文件上传</title>
<script>
    $(document).ready(function() {
        $("#uploadButton").click(
                function() {                             
                       var xhr;
                       if(window.XMLHttpRequest){
                    	   //IE7+,Firefox,Chrome,Opera,Safari浏览器执行的代码
                    	   xhr = new XMLHttpRequest();
                       }else{
                    	   //IE6,IE5浏览器执行的代码
                    	   xhr = new ActiveXObject("Microsoft.XMLHTTP");
                       }                      
                        xhr.open("post","ajaxFileUpload");
                        xhr.onreadystatechange = function() {   
                        	if(xhr.readyState == 4){
                        		 if(xhr.status == 200){
                                     alert("文件上传成功"); 
                                 }else{
                                     alert("文件上传失败")
                                 }    
                        	}                         
                        };
                   var file1 = $("#file1")[0].files[0];                
                    var username=$("#userName").val();
                    /* FormData对象用以将数据编译成键值对,以便用XMLHttpRequest来发送数据。其主要用于发送表单数据,
                                                             但亦可用于发送带键数据(keyed data),而独立于表单使用。如果表单enctype属性设为multipart/form-data ,
                                                               则会使用表单的submit()方法来发送数据,从而,发送数据具有同样形式。 */
                    //通过FormData构造函数创建一个空对象
                    var myForm = new FormData();
                    //通过append()方法来追加数据
                    myForm.append("userName",username);
                    myForm.append("file1", file1);   
                    xhr.send(myForm);
                });
    });
</script>
</head>
<body style="margin: 0 auto; text-align: center;">
	<p id="previewImage"></p>
	<form action="fileUpload" enctype="multipart/form-data" method="post">
		<label for="userName">用户名</label> <input type="text" id="userName"
			name="userName" /> <label for="file1">请选择文件</label> <input
			type="file" id="file1" name="file1" />
		<button type="button" id="uploadButton" class="btn btn-primary">上传</button>
	</form>
</body>
</html>

   2.Servlet代码

   

package com.ajaxuploadtest.app;

import java.io.IOException;
import java.util.Date;
import java.util.UUID;

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

/*@MultipartConfig标注可用来设置Servlet处理上传文件的相关信息,如果没有设置属性则取默认值

可用属性如下:
1:fileSizeThreshold:整数值设置,若上传文件大小超过设置门槛,则先放入缓存文件,默认值为0;
2:location:字符串设置,设置写入文件时的目录,如果设置这个属性值,则缓存文件就是写到指定的目录,也可搭配Part的write()方法使用,默认为空字符串。
3:maxFileSize:限制上传文件大小,默认值为-1L,表示无限制
4:maxRequestSize:限制multipart/form-data请求个数,默认值为-1L,表示不限制个数
*/
@MultipartConfig(location="E:\\uploads", fileSizeThreshold=1024*1024,
maxFileSize=1024*1024*20, maxRequestSize=1024*1024*5*5)
@WebServlet(urlPatterns={"/ajaxFileUpload"},loadOnStartup=1)
public class AjaxFileUpload extends HttpServlet {
    

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
        request.setCharacterEncoding("UTF-8");

        //Servlet3.0新增了request.getParts()/getPart(String filename) api,用于获取使用multipart/form-data格式传递的http请求的请求体,通常用于获取上传文件。
        Part part=request.getPart("file1");
        //Servlet3没有提供直接获取文件名的方法,需要从请求头中解析出来
        //获取请求头,请求头的格式:form-data; name="file"; filename="snmp4j--api.zip"
        String header = part.getHeader("content-disposition");
        //获取文件名
        String fileName = getFileName(header);
        
        System.out.println("fileName:"+fileName);
        part.write(fileName);
        
        response.setContentType("application/json;charset=utf-8");
        
        String s="{\"result\":\"success\"}";
        response.getWriter().print(s);
    }
    
    
    /**
     * 根据请求头解析出文件名
     * 请求头的格式:火狐和google浏览器下:form-data; name="file"; filename="test.doc"
     *          IE浏览器下:form-data; name="file"; filename="E:\test.doc"
     * @param header 请求头
     * @return 文件名
     */
    public String getFileName(String header) {
        /**
         * String[] tempArr1 = header.split(";");代码执行完之后,在不同的浏览器下,tempArr1
           数组里面的内容稍有区别
         * 火狐或者google浏览器下:tempArr1={form-data,name="file",filename="test.doc"}
         * IE浏览器下:tempArr1={form-data,name="file",filename="E:\test.doc"}
         */
        String[] tempArr1 = header.split(";");
        /**
         *火狐或者google浏览器下:tempArr2={filename,"test.doc"}
         *IE浏览器下:tempArr2={filename,"E:\test.doc"}
         */
        String[] tempArr2 = tempArr1[2].split("=");
        //获取文件名,兼容各种浏览器的写法
        String fileName = 
           tempArr2[1].substring(tempArr2[1].lastIndexOf("\\")+1).replaceAll("\"", "");
        return fileName;
    }
  

}

   二、上传带多个文件的表单

   

      1.JSP页面代码

    

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<script type="text/javascript" src="jquery/jquery-3.3.1.js"></script>
<script type="text/javascript" src="bootstrap/bootstrap.js"></script>
<link href="bootstrap/bootstrap.css" rel="stylesheet">
<title>AJAX文件上传</title>
<script>
    $(document).ready(function() {
        $("#uploadButton").click(
                function() {                             
                       var xhr;
                       if(window.XMLHttpRequest){
                    	   //IE7+,Firefox,Chrome,Opera,Safari浏览器执行的代码
                    	   xhr = new XMLHttpRequest();
                       }else{
                    	   //IE6,IE5浏览器执行的代码
                    	   xhr = new ActiveXObject("Microsoft.XMLHTTP");
                       }                      
                        xhr.open("post","ajaxFileUpload");
                        xhr.onreadystatechange = function() {   
                        	if(xhr.readyState == 4){
                        		 if(xhr.status == 200){
                                     alert("文件上传成功"); 
                                 }else{
                                     alert("文件上传失败")
                                 }    
                        	}                         
                        };
                   var file1 = $("#file1")[0].files[0];  
                   var file2 = $("#file2")[0].files[0];
                    var username=$("#userName").val();
                    /* FormData对象用以将数据编译成键值对,以便用XMLHttpRequest来发送数据。其主要用于发送表单数据,
                                                             但亦可用于发送带键数据(keyed data),而独立于表单使用。如果表单enctype属性设为multipart/form-data ,
                                                               则会使用表单的submit()方法来发送数据,从而,发送数据具有同样形式。 */
                    //通过FormData构造函数创建一个空对象
                    var myForm = new FormData();
                    //通过append()方法来追加数据
                    myForm.append("userName",username);
                    myForm.append("file1", file1);  
                    myForm.append("file2", file2);
                    xhr.send(myForm);
                });
    });
</script>
</head>
<body style="margin: 0 auto; text-align: center;">
	<p id="previewImage"></p>
	<form action="fileUpload" enctype="multipart/form-data" method="post">
		<label for="userName">用户名</label> 
		<input type="text" id="userName" name="userName" /><br>
		<label for="file1">请选择文件</label>
	    <input type="file" id="file1" name="file1" /><br>
	    <label for="file2">请选择文件</label>
	    <input type="file" id="file2" name="file2" /><br>
		<button type="button" id="uploadButton" class="btn btn-primary">提交</button>
	</form>
</body>
</html>

 2.Servlet代码

  

package com.ajaxuploadtest.app;

import java.io.IOException;
import java.util.Collection;
import java.util.Date;
import java.util.UUID;

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

/*@MultipartConfig标注可用来设置Servlet处理上传文件的相关信息,如果没有设置属性则取默认值

可用属性如下:
1:fileSizeThreshold:整数值设置,若上传文件大小超过设置门槛,则先放入缓存文件,默认值为0;
2:location:字符串设置,设置写入文件时的目录,如果设置这个属性值,则缓存文件就是写到指定的目录,也可搭配Part的write()方法使用,默认为空字符串。
3:maxFileSize:限制上传文件大小,默认值为-1L,表示无限制
4:maxRequestSize:限制multipart/form-data请求个数,默认值为-1L,表示不限制个数
*/
@MultipartConfig(location = "E:\\uploads", fileSizeThreshold = 1024 * 1024, maxFileSize = 1024 * 1024
		* 20, maxRequestSize = 1024 * 1024 * 10 * 10)
@WebServlet(urlPatterns = { "/ajaxFileUpload" }, loadOnStartup = 1)
public class AjaxFileUpload extends HttpServlet {

	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// TODO Auto-generated method stub
		request.setCharacterEncoding("UTF-8");

		// Servlet3.0新增了request.getParts()/getPart(String filename)
		// api,用于获取使用multipart/form-data格式传递的http请求的请求体,通常用于获取上传文件。
		// 获取上传的文件集合
		Collection<Part> parts = request.getParts();
		System.out.println("parts.size:" + parts.size());
		// 上传单个文件
		if (parts.size() == 1) {
			// Servlet3.0将multipart/form-data的POST请求封装成Part,通过Part对上传的文件进行操作。
			// Part part = parts[0];//从上传的文件集合中获取Part对象
			Part part = request.getPart("file1");// 通过表单file控件的名字直接获取Part对象
			// Servlet3没有提供直接获取文件名的方法,需要从请求头中解析出来
			// 获取请求头,请求头的格式:form-data; name="file"; filename="test.doc"
			String header = part.getHeader("content-disposition");
			// 获取文件名
			String fileName = getFileName(header);
			// 把文件写到指定路径
			part.write(fileName);

		} else {
			// 一次性上传多个文件
			// 可以通过Part part = request.getPart("file1");的方式去逐个获取每个文件
			// 也可以通过foreach循环去处理,这个循环方式适合只上传文件时。
			for (Part part : parts) {
				// 判断是否为文件,如word文档类型为:application/msword,图片类型为:image开头,若为普通的数据为null
				String contentType = "" + part.getContentType();
				if (contentType.startsWith("application") || contentType.startsWith("image")) {
					// 获取请求头,请求头的格式:form-data; name="file"; filename="test.doc"
					String header = part.getHeader("content-disposition");
					// 获取文件名
					String fileName = getFileName(header);
					// 把文件写到指定路径
					part.write(fileName);
				}
			}
		}

		// 获取表单中普通的数据
		String userName = request.getParameter("userName");
		System.out.println("userName" + userName);

		response.setContentType("application/json;charset=utf-8");

		String s = "{\"result\":\"success\"}";
		response.getWriter().print(s);
	}

	public String getFileName(String header) {
		/**
		 * String[] tempArr1 = header.split(";");代码执行完之后,在不同的浏览器下,tempArr1数组里面的内容稍有区别
		 * 火狐或者google浏览器下:tempArr1={form-data,name="file",filename="test.doc"}
		 * IE浏览器下:tempArr1={form-data,name="file",filename="E:\test.doc"}
		 */
		String[] tempArr1 = header.split(";");
		/**
		 * 火狐或者google浏览器下:tempArr2={filename,"test.doc"}
		 * IE浏览器下:tempArr2={filename,"E:\test.doc"}
		 */
		String[] tempArr2 = tempArr1[2].split("=");
		// 获取文件名,兼容各种浏览器的写法
		String fileName = tempArr2[1].substring(tempArr2[1].lastIndexOf("\\") + 1).replaceAll("\"", "");
		return fileName;
	}

}

猜你喜欢

转载自blog.csdn.net/qq_40348465/article/details/84630275