ajax上傳文件(ajax+Struts1 & ajax+servlet+上傳進度條)

一、Struts1 ajax上傳文件
input框

<input type="button" value="上傳" onclick="uploadFile()" > 
<input  id="fileId" type="file" name="billfile" style="width: 200px;height: 20px"></input>

ajax請求(注意需要使用支持FormData對象的jquery版本)

FormData 對象的在jquery中使用
1.創建:var formData = new formData();

2.添加鍵值對:formData.append('key','value');
  formData.append("formFile",$('#fileId')[0].files[0]);

3.發送數據:
	$.ajax({
		url:"<%=request.getContextPath()%>/impDataAction.do?type=uploadFile",
		type: "POST",
		data: formData,
		processData : false, // 告訴jQuery不要去處理髮送的數據(必須設置)
		contentType : false, // 告訴jQuery不要去設置Content-Type請求頭(必須設置)
		success: function(data) {
		    alert("ok");
		},
		error: function(request) {
			alert("Connection error");
		}
	});
}



Struts配置:

action配置,重點在於impDataForm與ImpDataAction
<action  path="/impDataAction" type="com.mycim.webapp.actions.maintain.ImpDataAction" name="impDataForm" scope="request"
	 input="/maintain/impdata.jsp">
</action>

java代碼:

if(StringUtils.equals(getParameter("type", request), "uploadFile")){
        	try {
        		FormFile formFile = impDataForm.getFormFile();
        		InputStream in = formFile.getInputStream();
        		FileOutputStream out = new FileOutputStream("D:/Users/uniz/Desktop/test/"+formFile.getFileName());
        		byte[] buf = new byte[1024];
        		int len;
        		while ((len = in.read(buf)) != -1) {
        		   out.write(buf, 0, len);
        		}
        		in.close();
        		out.close();
        	} catch (Exception e) {
        	}
        	return WebUtil.NULLActionForward;
        }

二、Ajax + Servlet + 上傳進度條
需要jar包

	<dependency>
	    <groupId>commons-fileupload</groupId>
	    <artifactId>commons-fileupload</artifactId>
	    <version>1.3.3</version>
	</dependency>
	<dependency>
	    <groupId>commons-io</groupId>
	    <artifactId>commons-io</artifactId>
	    <version>2.6</version>
	</dependency>

jsp&ajax&上傳進度條

<%@ page contentType="text/html;charset=UTF-8"%>
<%@ page language="java"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<%@ include file="/app/common/head.jsp"%>
<style type="text/css">
.progress {
   width: 600px;
    height: 10px;
    border: 1px solid #ccc;
    border-radius: 10px;
    margin: 10px 0px;
    overflow: hidden;
}
/* 初始狀態設置進度條寬度爲0px */
.progress > div {
    width: 0px;     
    height: 100%;
    background-color: yellowgreen;
    transition: all .3s ease;
}
</style>
</head>

<body>
<div class="progress">
    <div></div>
</div>
	<form id="myForm" action="" method="post" enctype="multipart/form-data">
	 選擇一個文件:<br/>
    <input type="file" id='fileName1'  name="uploadFile" /><!-- 文件必須要有ID --><br/>
    <input type="file" id='fileName2'  name="uploadFile2" /><br/>
    <input type="text" value="文件中文說明" name="cnfield" /><br/>
    <input type="button" onclick='doupload()' value="ajax upload" /><br/>
    <input type="submit" value="提交表單upload" />
	</form>
</body>
<script type="text/javascript">
$(function(){
	$("form").attr("action", getProPath()+"/UploadServlet");
});
function checkAndGetFile(file){//check文件大小
	if(file == undefined){
		alert('文件不存在!');
		return false;
	}
	if(file.size > 1024*1024*500){
		alert('文件大於500M,不允許上傳!');
		return false;
	}
	return true;
}
function buildFormData(){
	var formData = new FormData();
	formData.append('fieldName',$('#fileName1')[0].files[0]);
    formData.append('fieldName',document.getElementsByName('uploadFile2')[0].files[0]);
    formData.append('fileDesc',$('input[name="cnfield"]').val());
    return formData;
}
function doupload(){
	if(!checkAndGetFile($('#fileName1')[0].files[0])){
		return;
	}
	var formData = buildFormData();
	$.ajax({
        url:$("form").attr("action"), 
        dataType:'json',
        type:'POST',
        async: true,//顯示上傳進度條需要異步
        cache: false,
        data: formData,
        processData : false, // 對錶單data數據是否進行序列化,不做處理
        contentType : false,// 不要設置Content-Type請求頭
        timeout:120000,
        success: function(data){
        	console.log(data);
        	if(data.success){
        		alert(data.msg.uploadMsg);
        	}
        },
        error:function(xhr, textStatus, errorThrown){
        	console.log(xhr);
			alert("ajax error textStatus = " + textStatus+", errorThrown = " + errorThrown);
        },
        complete:function(){
        	initProgressBar();
        },
        xhr: function () {
            var myXhr = $.ajaxSettings.xhr();
            if (myXhr.upload) {//使用myXhr.upload監聽上傳過程,註冊progress事件
                myXhr.upload.addEventListener('progress', function(event){
                	refreshProgressBar(event);
                }, false);
            }
            return myXhr; //xhr對象返回給jQuery使用
        }
    });
}
function refreshProgressBar(event){
	var progressRate = (event.loaded / event.total) * 100 + '%';
	$('.progress > div').css('width', progressRate);
}
function initProgressBar(){
	$('.progress > div').css('width', 0);
}
</script>
</html>

servlet

package com.study.file;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

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.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.fileupload.servlet.ServletRequestContext;
import org.apache.commons.lang.StringUtils;

import com.study.json.JSONUtils;
import com.study.json.ReponseJSONBuilder;
import com.study.util.WebUtils;

/**
 * 特別注意,上傳文件遇到異常時,瀏覽器端接收不到異常信息。
 * 原因是上傳文件時瀏覽器請求持續時間長(文件未上傳完),發生異常後,服務器雖然立即捕獲異常並響應給瀏覽器,
 * 但是瀏覽器仍然在發送上傳請求,接收不到異常信息。
 * @author uniz
 */
@WebServlet("/UploadServlet")
public class UploadServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
     
    // 上傳文件存儲目錄
    private static final String UPLOAD_DIRECTORY = "uploadDir";
 
    // 上傳配置
    private static final int MEMORY_THRESHOLD   = 1024 * 1024 * 300*3;  // 300MB
    private static final int MAX_FILE_SIZE      = 1024 * 1024 * 400*3; // 400MB
    private static final int MAX_REQUEST_SIZE   = 1024 * 1024 * 500*3; // 500MB
 
    /**
     * 上傳數據及保存文件
     */
    @SuppressWarnings("rawtypes")
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    	request.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=utf-8");
    	if(isAjax(request)) {
    		try {
    			Map result = uploadHander(request);
				WebUtils.writeJson(response, ReponseJSONBuilder.buildSuccessMsg(JSONUtils.toJSONString(result)));
			} catch (Exception e) {
				e.printStackTrace();
				WebUtils.writeJson(response, ReponseJSONBuilder.buildErrorMsg(e));
			}
			return ;
    	}else {
    		Map result = uploadHander(request);
    		request.setAttribute("uploadFlag", MapUtils.getBooleanValue(result, "uploadFlag"));
    		request.setAttribute("message", MapUtils.getString(result, "uploadMsg")
    				+ " uploadFiles = " + MapUtils.getString(result, "uploadFiles") + "");
    		
    		request.getRequestDispatcher("/uploadfile/message.jsp").forward(request, response);
    	}
    }

	private void checkUploadFile(HttpServletRequest request) throws Exception {
		ServletRequestContext ctx = new ServletRequestContext(request);
        long requestSize = ctx.contentLength();
        if(requestSize > MAX_REQUEST_SIZE) {
        	throw new Exception("上傳文件大小超過最大允許值!");
        }
        
 		if (!ServletFileUpload.isMultipartContent(request)) {
 			throw new Exception("只能 multipart/form-data 類型數據");
 		}
	}

	private boolean isAjax(HttpServletRequest req) {
		boolean isAjaxRequest = false;  
        if("XMLHttpRequest".equalsIgnoreCase(req.getHeader("x-requested-with"))){  
            isAjaxRequest = true;  
        }  
		return isAjaxRequest;
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	private Map uploadHander(HttpServletRequest request) {
		List<Map> uploadFiles = new ArrayList<Map>();
		boolean uploadFlag = false;
		String uploadMsg = "";
		try {
			
			checkUploadFile(request);
			
			uploadFiles = doUpload(request);
			
			if(CollectionUtils.isNotEmpty(uploadFiles)) {
				
				uploadFlag = true;
				
				uploadMsg = "上傳成功!";
			}else {
				uploadMsg = "沒有上傳內容!";
			}
			
		} catch (Exception e) {
			uploadMsg = e.getMessage();
		}
		
		Map result = new HashMap();
		result.put("uploadFlag", uploadFlag);
		result.put("uploadMsg", uploadMsg);
		result.put("uploadFiles", uploadFiles);
		return result;
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	private List<Map> doUpload(HttpServletRequest request) throws Exception {// 配置上傳參數
		List<Map> uploadFiles = new ArrayList<Map>();
		
		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 = "D:\\study\\eclipse201812R-workspace\\uniz\\src\\main\\webapp\\uploadfile\\" + UPLOAD_DIRECTORY;
		
		// 如果目錄不存在則創建
		File uploadDir = new File(uploadPath);

		if (!uploadDir.exists()) {
			uploadDir.mkdir();
		}

		// 解析請求的內容提取文件數據
		List<FileItem> formItems = upload.parseRequest(request);
		
		if (CollectionUtils.isNotEmpty(formItems)) {
			// 迭代表單數據
			for (FileItem item : formItems) {
				if (!item.isFormField()) {
					if(StringUtils.isBlank(item.getName())) {
						continue;//throw new Exception("文件名不能爲空,請選擇上傳文件!");
					}
					
					String fileName = new File(item.getName()).getName();
					String filePath = uploadPath + File.separator + fileName;
					
					File storeFile = new File(filePath);//文件的上傳路徑
					
					item.write(storeFile);// 保存文件到硬盤
					
					Map map = new HashMap();
					map.put("fieldType", "文件");
					map.put("fileName", fileName);
					map.put("filePath", filePath);
					map.put("fieldName", item.getFieldName());//ajax FormData中的key
					map.put("fileSize", item.getSize());
					uploadFiles.add(map);
				}else {
					Map map = new HashMap();
					map.put("fieldType", "普通字段");
					map.put("fieldName", item.getFieldName());//ajax FormData中的key
					map.put("fieldValue", item.getString("UTF-8"));
					map.put("fileSize", item.getSize());
					uploadFiles.add(map);
				}
			}
		}
		return uploadFiles;
	}
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章