1. 程式人生 > >AJAX實現圖片上傳和預覽(傳統ajax與jQuery AJAX;帶圖片的表單提交)

AJAX實現圖片上傳和預覽(傳統ajax與jQuery AJAX;帶圖片的表單提交)

  一、通過Servlet3.0和傳統的AJAX實現圖片上傳和預覽

         此方法也適用於帶圖片的表單提交   

     上傳時預覽圖片

    點選上傳按鈕,上傳到相應的檔案中

    

       1.JSP頁面程式碼(通過ajax將圖片傳到後臺,並進行圖片預覽)

      

<%@ 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() {
    	$("#previewImage").hide();
        $("#imageFile").change(function() {
            var fileReader = new FileReader();
            fileReader.onload = function(e) {
            	$("#previewImage").show();
            	$("#previewImage").attr('src',e.target.result);
            }
            var imageFile = this.files[0];
            fileReader.readAsDataURL(imageFile);
        });
        $("#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 imageFile = $("#imageFile")[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("imageFile", imageFile);
                    xhr.send(myForm);
                });
    });
</script>
</head>
<body style="margin: 0 auto; text-align: center;">
    <img id="previewImage" alt="預覽圖" width="200px"
			height="200px" />
	<!-- <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="imageFile">上傳圖片</label> 
		<input type="file" id="imageFile" name="imageFile" accept="image/jpeg" />
		
		<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
		* 5, 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");
		/*
		 * UUID.randomUUID().toString()是javaJDK提供的一個自動生成主鍵的方法。 UUID(Universally Unique
		 * Identifier)全域性唯一識別符號,是指在一臺機器上生成的數字,它保證對在同一時空中的所有機器都是唯一的,是由一個十六位的數字組成,表現出來的 形式。
		 * 由以下幾部分的組合:當前日期和時間(UUID的第一個部分與時間有關,如果你在生成一個UUID之後,過幾秒又生成一個UUID,則第一個部分不
		 * 同,其餘相同),時鐘序列,全域性唯一的IEEE機器識別號(如果有網絡卡,從網絡卡獲得,沒有網絡卡以其他方式獲得), UUID的唯一缺陷在於生成的結果串會比較長。
		 */
		String fileName = UUID.randomUUID().toString() + ".jpg";

		// Servlet3.0新增了request.getParts()/getPart(String filename)
		// api,用於獲取使用multipart/form-data格式傳遞的http請求的請求體,通常用於獲取上傳檔案。
		Part part = request.getPart("imageFile");
		System.out.println("fileName:" + fileName);
		part.write(fileName);

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

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

}

  一、jQuery AJAX實現圖片上傳和預覽

  

    1.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=ISO-8859-1">
<title>Insert title here</title>
<script type="text/javascript" src="jquery/jquery-3.3.1.js"></script>
<link href="bootstrap/bootstrap.css" rel="stylesheet">
<script type="text/javascript">
	function doUpload() {
		var formData = new FormData($("#uploadForm")[0]);//構造FormData物件
		$.ajax({
			url : 'ajaxFileUpload',//接受請求的Servlet地址
			type : 'POST',
			data : formData,
			async : false,//同步請求
			cache : false,//不快取頁面
			contentType : false,//當form以multipart/form-data方式上傳檔案時,需要設定為false
			processData : false,//如果要傳送Dom樹資訊或其他不需要轉換的資訊,請設定為false
			success : function(url) {
				$("#img_test").attr('src', url);//上傳成功後,把伺服器獲取到的圖片路徑繫結到img標籤是src屬性上
			},
			error : function(returndata) {
				alert(returndata);
			}

		});
	}
	//如果想要使用者一改變選擇的檔案就出現預覽圖,可以採取如下方法
	/*  $(function() {
		$("#file").onchange(){
			doUpload();
		};	
	}); */
</script>
</head>
<body style="margin: 0 auto; text-align: center;">
	<form id="uploadForm">
		<label for="file">圖片:</label> <input type="file" name="file" id="file" /><br>
		<input type="button" value="上傳" onclick="doUpload()"
			class="btn btn-primary" />
	</form>
	<img id="img_test" alt="" width="200px" height="300px" />

</body>
</html>

   2.Servlet程式碼

   

package com.ajaxuploadtest.app;

import java.io.File;
import java.io.IOException;
import java.util.List;

import javax.servlet.ServletContext;
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 org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

/**
 * Servlet implementation class AjaxUploadServelt
 */
@WebServlet("/ajaxFileUpload")
public class AjaxUpload extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public AjaxUpload() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		response.getWriter().append("Served at: ").append(request.getContextPath());
	}
	
	
	private String saveFile(FileItem item) {
		//此處獲取的是檔案的全路徑
		String fileFullName = item.getName();
		File fileInfo = new File(fileFullName);
		String fileName = fileInfo.getName(); 
		//String fileName = fileFullName.substring(fileFullName.lastIndexOf("\\") + 1);
		//獲取當前專案的根目錄
		String root = this.getServletContext().getRealPath("//");
		//String root ="E:\\eclipse-workspace\\JAVAWeb\\AjaxUploadTest2\\WebContent";
		//儲存路徑為當前工程根目錄的upload資料夾
		File savePath = new File(root+File.separator+"upload");
		//如果路徑不存在,就新建目錄
		if(!savePath.exists()) {
			savePath.mkdir();
		}
		File uploadedFile = new File(savePath+File.separator+fileName);		
		try {
			item.write(uploadedFile);//寫入
			//檔案的服務路徑:工程目錄+upload+檔名
			return this.getServletContext().getContextPath()+"//upload//"+fileName;

		} catch (Exception e) {
			// TODO Auto-generated catch block
			System.out.println("儲存檔案失敗");
			return "";
		}
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub		
		//藉助工具解析
		//判斷傳入的是否是檔案型別
		boolean isMultipart =ServletFileUpload.isMultipartContent(request);

		if(isMultipart){
			//建立FileItem物件工廠
			DiskFileItemFactory factory = new DiskFileItemFactory();
			// 獲取Servlet上下文
			ServletContext servletContext = this.getServletConfig().getServletContext();
			//獲取臨時資料夾
			File repository = (File) servletContext.getAttribute("javax.servlet.context.tempdir");
			factory.setRepository(repository);
			//建立檔案上傳處理器
			ServletFileUpload upload = new ServletFileUpload((FileItemFactory) factory);
			//解決中文亂碼引數
			upload.setHeaderEncoding("utf-8");
			// 解析request獲取上傳的引數
			// 使用ServletFileUpload解析器解析上傳資料,解析結果返回的是一個List<FileItem>集合,每一個FileItem對應一個Form表單的輸入項
			List<FileItem> items = null;
			try {
				items = upload.parseRequest(request);
			} catch (FileUploadException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			// 解決上傳檔名的中文亂碼
			upload.setHeaderEncoding("UTF-8");
			String filePath = "";
			// 處理引數
			for(FileItem item:items) {
				// 判斷是否為Form的表單域,即判斷是否為普通的資料,若不是則為檔案。
				if(item.isFormField()) {
					//對錶單域資料的處理,若僅上傳檔案,此處可不必關注
					String name = item.getFieldName();
					// 解決普通輸入項的資料的中文亂碼問題
					String value = item.getString("UTF-8");
				}else {	
					//對檔案資料進行儲存
					filePath=saveFile(item);
				}
			}
			//返回圖片的路徑
			response.getWriter().write(filePath);			
		}

	}
	private List<FileItem> getRequestFileItems(HttpServletRequest request) {
		// TODO Auto-generated method stub
		return null;
	}
}