JSP/Servlet --- 上傳文件

本篇是servlet和jsp學習指南一書的示例代碼加上自己理解,以及在寫的過程中遇到的問題

servlet 4.0文檔

javax.servlet.http.Part(Interface)

This class represents a part as uploaded to the server as part of a multipart/form-data request body. The part may represent either an uploaded file or form data.

自從servlet3.0開始就有了這個接口,該接口表示上傳到服務器的multipart/form-data請求的主體部分。該部分可能是上傳的文件或是表單數據

下面使用了write方法

void write(java.lang.String fileName)
    throws java.io.IOException

這是一種將上傳的part寫入磁盤的一種便捷方法。客戶端代碼並不關心該part是存儲在內存中,還是在臨時位置上的磁盤上。他們只是想把上傳的部分寫入文件。如果同一個part調用多次的write方法,則該方法不能保證成功。這允許特定的實現在可能的情況下使用文件重命名,而不是複製所有底層數據,從而獲得顯著的性能效益。(這句話不知道什麼意思,猜測是可以通過進行文件重命名來賦值文件,而不是重新copy所有底層數據)

其中有個方法是servlet3.1新出的

java.lang.String getSubmittedFileName()
返回上傳文件的名字,若不存在則返回null,所以這裏需要進行判斷

上傳單個文件

uploadfile.jsp頁面

<%@ page contentType="text/html; charset=UTF-8"%>
<html>
<head>
<title>upload file</title>
</head>
<body>
	<!-- enctype規定在發送到服務器之前應該如何對錶單數據進行編碼 -->
	<!-- multipart/form-data不對字符編碼,在使用包含文件上傳控件的表單時,必須使用該值 -->
	<form method="post" action="/ServletModel/model/UploadServlet" enctype="multipart/form-data">
		作者: <input type="text" name="author"/><br/>
                選擇文件:
		<input type="file" name="upload_file">
		<input type="submit" value="上傳"/>
	</form>
        <br/>${hint}
</body>
</html>

UploadServlet.java,servlet

package com.xck.model.servlet;

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;

@WebServlet(name="UploadServlet", urlPatterns={"/model/UploadServlet"})
//說明該Servlet處理的是multipart/form-data類型的請求,是Servlet3.0提供的對文件上傳的支持
@MultipartConfig
public class UploadServlet extends HttpServlet{

	private static final long serialVersionUID = 1L;
	
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException{
		//Servlet3.0中新引入的方法,用來處理multipart/form-data類型編碼的表單
		//可以用request.getPart("..")方法獲得name爲upload—_file的上傳附件
		//多文件上傳request.getParts(),然後通過循環分別處理每一個上傳附件
		request.setCharacterEncoding("UTF-8");
		//通過html標籤name屬性值獲取
                Part part = request.getPart("upload_file");
		String fileName = getFileName(part);
		if(fileName!=null && !fileName.isEmpty()){
                    String path = request.getServletContext().getRealPath("\\upload") + "\\" + fileName;
		    System.out.println(path);
		    part.write(path);
		    //響應 這裏同樣要設置編碼
                    response.setContentType("text/html; charset=UTF-8");
                    PrintWriter writer = response.getWriter();
                    writer.print("<br/>Uploaded file name: " + fileName);
                    writer.print("<br/>file size: " + part.getSize());
                    String author = request.getParameter("author");
                    writer.print("<br/>author: " + author);
                }else{
                    request.setAttribute("hint", "上傳失敗,上傳文件名或路徑有問題");
                    //這裏若沒有加上/會跳轉到 /model/uploadfile.jsp多了個model
                    request.getRequestDispatcher("/uploadfile.jsp").forward(request, response);
                }
	}
	
        /**
         * 獲取上傳的文體名
         * @param part
         * @return 上傳文件名
         */
	private String getFileName(Part part){
		if(part == null){
			return null;
		}
		//Tomcat7下並沒有getSubmittedFileName方法可以直接獲取名字
		//上傳文件請求頭中會有content-disposition
		//獲取請求頭中的Content-Disposition,裏面有表單信息,標籤name屬性值,filename上傳文件的路徑+文件名
		/*
		content-disposition example:
		
		form-data; name="upload_file"; 
		filename="D:\spring-framework-4.3.2.RELEASE-dist\spring-framework-4.3.2.RELEASE\libs\spring-webmvc-4.3.2.RELEASE-sources.jar"
		 */
		String contentDisposition = part.getHeader("Content-Disposition");
		String[] elements = contentDisposition.split(";"); //以分號作爲分隔符
		for(String element : elements){
			if(element.trim().startsWith("filename")){
				//+1是爲了跳過\,且字符串最後一個是引號,也要跳過,之前寫的時候沒注意,一直報錯FileNoFound
				return element.substring(element.lastIndexOf("\\")+1, element.length()-1);
			}
		}
		return null;
	}
}
還可以限制文件上傳的大小和類型等功能。。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章