1. 程式人生 > >【Servlet3.0新特性】第03節_檔案上傳

【Servlet3.0新特性】第03節_檔案上傳

完整版見https://jadyer.github.io/2013/06/24/servlet30-new-feature/

這是一個Web Project

首先是web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
	http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
	<!-- Servlet3.0需要Tomcat7和JavaEE6,配置方法詳見 -->
	<!-- http://blog.csdn.net/jadyer/article/details/9164655 -->
	<!-- http://blog.csdn.net/jadyer/article/details/9164737 -->
	<welcome-file-list>
		<welcome-file>index.jsp</welcome-file>
	</welcome-file-list>
</web-app>

下面是表單輸入頁index.jsp

<%@ page language="java" pageEncoding="UTF-8"%>
<form action="<%=request.getContextPath()%>/upload" method="POST" enctype="multipart/form-data">
	<input name="uploadFile" type="file"><br/>
	<input type="submit">
<form>

最後是用於處理檔案上傳的HelloServlet.java
package com.jadyer.servlet;

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

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;

/**
 * Servlet3.0新特性之便利的檔案上傳
 * @see ------------------------------------------------------------------------------------------------------------------
 * @see 注意要使用@MultipartConfig註解標明此Servlet支援檔案上傳
 * @see 否則獲取到的javax.servlet.http.Part就是空的,Part.getXxx()就會報告NullPointerException
 * @see ------------------------------------------------------------------------------------------------------------------
 * @see 關於@MultipartConfig的幾個屬性
 * @see location--->指定儲存所上傳檔案的目錄....分以下兩種情況
 * @see             1)若part.write(fileName)傳的引數只有上傳的檔名,那麼最後檔案就會被上傳到location目錄中
 * @see               若此時location所指定的目錄不存在,則會報告下面的異常(Tomcat7.x啟動時不會報)
 * @see               java.io.IOException: The temporary upload location [D:\\upload\22] is not valid
 * @see             2)若part.write(savePath+"/"+fileName),則無論location是否指定目錄,最後檔案都會被上傳到savePath
 * @see               但是,如果此時location所指定的目錄不存在,那麼也會報告第一種情況中的異常,並導致上傳檔案失敗
 * @see             總結:API說location是儲存檔案的目錄,但根據上面兩種情況,我感覺location指的是臨時檔案目錄,故不推薦使用
 * @see             總結:隨後我又查看了Oracle官方文件,發現該屬性指的就是臨時檔案目錄
 * @see             總結:其官方文件的地址為http://docs.oracle.com/javaee/6/tutorial/doc/gmhal.html
 * @see fileSizeThreshold-->設定閾值,達到閾值後會將所上傳的檔案從臨時目錄中寫到磁碟..單位為byte,預設值是0
 * @see maxFileSize-------->允許上傳的單個檔案最大值,即不限制檔案總數及總大小,只限制單個檔案..單位為byte,預設值是-1,即無限制
 * @see maxRequestSize----->允許上傳的檔案的最大值,這裡指的是一次性上傳的所有檔案的合計大小..單位也是byte,預設值是-1,即無限制
 * @see ------------------------------------------------------------------------------------------------------------------
 * @create Jun 24, 2013 3:19:12 PM
 * @author 玄玉<http://blog.csdn.net/jadyer>
 */
@WebServlet(urlPatterns="/upload")
@MultipartConfig(fileSizeThreshold=1024*1024*2, maxFileSize=1024*1024*20, maxRequestSize=1024*1024*200)
public class HelloServlet extends HttpServlet {
	private static final long serialVersionUID = -1812698941752545746L;

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		//解決上傳檔案的中文亂碼問題
		req.setCharacterEncoding("UTF-8");
		//解決應答給瀏覽器的中文亂碼問題
		resp.setCharacterEncoding("UTF-8");
		
		//回顯上傳結果給瀏覽器
		String uploadResult = null;
		PrintWriter out = resp.getWriter();
		resp.setContentType("text/html; charset=UTF-8");
		try{
			//獲取上傳的檔案的Part,下面的操作都是以這個Part為中心的
			Part part = req.getPart("uploadFile");
			
			//本例中它的值是form-data; name="uploadFile"; filename="玄玉.png"
			String _str = part.getHeader("content-disposition");
			//獲取上傳的檔案真實名字(含字尾)
			String fileName = _str.substring(_str.lastIndexOf("=")+2, _str.lastIndexOf("\""));
			
			//指定上傳的檔案的儲存目錄並確保其存在
			String savePath = "D:/upload/";
			File savePathFolder = new File(savePath);
			if(!savePathFolder.exists()){
				savePathFolder.mkdirs();
			}
			//上傳檔案(寫入磁碟)
			part.write(savePath + "/" + fileName);
			uploadResult = "上傳完畢<br/>上傳的檔案Part=" + part.getName() + "<br/>上傳的檔名稱=" + fileName
						 + "<br/>上傳的檔案大小=" + part.getSize() + "<br/>上傳的檔案型別=" + part.getContentType();
		}catch(IllegalStateException ise){
			uploadResult = "上傳失敗,失敗原因如下<br/>" + ise.getMessage();
		}
		out.print(uploadResult);
		out.flush();
		out.close();
	}
}