SpringMVC 實現文件上傳與下載,並配置異常頁面

目錄


上傳文件的表單要求html

Spring MVC實現上傳文件java

須要導入的jar包web

配置MultipartResolver解析器spring

編寫接收上傳文件的控制器apache

Spring MVC實現文件下載編程

下載文件時的header設置數組

編寫文件下載的控制器瀏覽器

Spring MVC配置異常跳轉的頁面安全

配置異常頁面的介紹服務器

配置ExceptionResolver解析器

 

 

 


 

 

 

上傳文件的表單要求

  對於普通表單來講,有幾個注意點:

  一、action:表示要提交到哪裏;

  二、method:表單提交的方式,經常使用的有post和get兩種,不寫的話,默認是get;提交文件是隻能使用post方式。

  三、enctype:編碼類型,表示提交的數據是什麼格式。有三個值,

    1)不顯式設置enctype時,默認是application/x-www-form-urlencoded,表示提交的是普通的數據;

    2)text/plain,表示提交的是文本數據,數據量稍大一點。

    3)multipart/form-data,這種方式能夠提交二進制數據(音頻、圖像等文件)

  綜上,若是要上傳文件,必需要將method設置爲post,而後將enctype設置multipart/form-data。另外,上傳文件的input標籤的type屬性設置爲file。

<form action="upload" method="post" enctype="multipart/form-data">
	<input type="file" name="myfile" />
	<input type="submit" name="submit" value="upload" />
</form>

  

 

Spring MVC實現上傳文件

  在看Spring MVC是怎麼實現文件上傳以前,能夠先看一下不是框架,使用原生的servlet開發是怎麼實現文件上傳的:Servlet 實現文件上傳與下載

  在Servlet 3.0以後,Spring MVC實現文件上傳主要是使用一個叫MultipartResolver的解析器,該解析器依賴於apache的commons-io和commons-fileupload。MultipartResolver會自動解析文件,以後咱們在handlerMethod中,能夠很方便的操做上傳的文件。

 

  須要導入的jar包

  必不可少的commons-io.jar和commons-fileupload.jar這兩個包,缺一不可。

 

配置MultipartResolver解析器

  MultipartResolver是一個interface,咱們只須要配置他的一個實現類,好比CommonsMultipartResolver這個實現類,配置的方法也很簡單,只須要配置一個id爲multipartResolver的<bean>便可。

  在Spring MVC的配置文件中增長下面配置:

<!-- 建立MultipartResolver解析器 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
	<!-- 配置屬性,能夠省略不配置,設置上傳的文件maxSize,單位爲B(字節) -->
	<property name="maxUploadSize" value="1000000"></property>
</bean>

  

  編寫接收上傳文件的控制器

package cn.ganlixin.controller;

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

import org.apache.commons.io.FileUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;

@Controller
public class UploadController {

	@RequestMapping("upload")
	// 注意表單中文件input的name要和這裏的參數名相同。 
	public String upload(MultipartFile myfile) throws IOException {
		
		// 上傳一張圖片 C:\Users\Administrator\Desktop\code.png
		
		// 獲取文件的原始名稱
		String originalFileName = myfile.getOriginalFilename();  // code.png
		
		// 獲取上傳文件的表單中,input的name值,其實就是myfile(就是接收時的名稱)
		String fileName = myfile.getName();		// myfile
		
		// 獲取上傳的文件大小,單位爲字節
		long fileSize = myfile.getSize();		// 5823(字節)
		
		String extensionName = originalFileName.substring(originalFileName.lastIndexOf("."));
		
		/*
		進行一些過濾判斷操做
		 */
		
		// 利用apache的commons-io和commons-fileupload,將文件保存到硬盤中,文件名能夠根據本身的規則來定,這裏使用UUID
		String newFileName = UUID.randomUUID().toString();
		FileUtils.copyInputStreamToFile(
				myfile.getInputStream(), 
				new File("E:/uploads/" + newFileName + extensionName)
		);
		
		return "/success.jsp";
	}
}

  

 

Spring MVC實現文件下載

  在原生servlet實現文件下載主要有兩步:

  一、使用HttpServletRequest對象接收請求,獲取客戶端想要下載的文件名;

  二、讀取須要下載的文件,而後使用HttpServletResponse對象向客戶端輸出文件的字節流。

  其實Spring MVC實現文件下載和使用原生servlet實現文件下載的方式並無太大區別,甚至能夠說沒有任何區別。惟一的區別就是Spring MVC的控制器沒有繼承HttpServlet,可是卻能夠爲HandlerMethod注入HttpServletRequest和HttpServletResponse對象,以後就能夠進行和原生servlet相同的操做了。

 

  下載文件時的header設置

  先看一下提供下載文件的資源連接:

<a href="download?fileName=info.txt">點擊下載info.txt</a>
<a href="download?fileName=data.rar">點擊下載data.rar</a>

  若是仍舊按照之前的設置:Content-Type=text/html; charset=utf-8;    那麼當客戶端點擊下載連接時,發生的事情可能超乎預料。上面這兩個資源連接的文件的擴展名,擴展名指明瞭該文件的格式。若是沒有設置文件以附件形式下載,那麼對於不一樣的瀏覽器,對於文件的處理方式是不一樣的:

  一、若是瀏覽器可以打開或者可以解析該類型文件,那麼,文件就會直接被瀏覽器打開(注意,不是下載,不會保存到用戶的本地磁盤);

  二、若是瀏覽器不能打開或者不能解析該類型的文件,那麼,瀏覽器纔會將文件下載下來(保存到用戶磁盤)。

  好比,當服務器響應info.txt以後,瀏覽器接收到info.txt,info.txt是文本文件,瀏覽器能夠打開,因而就會將info.txt的內容顯示在瀏覽器的頁面中,而沒有下載下來。而對於data.rar來講,瀏覽器沒法直接打開,因此會下載到本地。

  爲了讓用戶請求下載的文件都能保存到用戶磁盤(即便瀏覽器可以打開文件,也不要讓他打開,而只是讓他進行下載),能夠設置Content-Disposition屬性爲attachment(通知瀏覽器以附件形式下載)。

 

  編寫文件下載的控制器

package cn.ganlixin.controller;

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

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.FileUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class DownloadController {

	@RequestMapping("/download")
	// 注入fileName、request、response
	public void download(String fileName, 
			HttpServletRequest request, HttpServletResponse response) throws IOException {
		
		// 設置響應是以附件形式,不用設置Content-Type了
		response.setHeader("Content-Disposition", "attachment; filename=" + fileName);
		
		// 獲取文件的真實路徑(可供下載的文件都放在/project/WebContext/files/路徑下,可是部署到服務器後,files文件夾的路徑都會發生改變。
		// 因此須要從新得到該文件從根目錄開始的路徑,而後讀取文件,並響應給客戶端。
		String path = request.getServletContext().getRealPath("files");
		
		// 文件下載時,是使用字節流格式,因此不能使用response.getWriter()-->返回PrintWriter是字符流
		// 獲取輸出字節流惡意使用response.
		ServletOutputStream out = response.getOutputStream();
		File downloadFile = new File(path, fileName);
		
		// 判斷文件是否存在
		if (! downloadFile.exists()) {
			request.setAttribute("msg", "文件不存在");
			response.sendError(404);
			return;
		}
		
		// 利用FileUtils將文件讀入字節數組,而後返回給客戶端。
		out.write(FileUtils.readFileToByteArray(downloadFile));
		out.flush();
		out.close();
	}
}

  

 

Spring MVC配置異常跳轉的頁面

  配置異常跳轉頁面的介紹

  咱們的服務器在運行過程當中可能會出現各類異常,當出現異常的時候,根據Java的脾氣,必定會打印堆棧信息,這個信息不能直接暴露給用戶,一個緣由是打印的堆棧信息並非用戶關心的內容,會影響用戶體驗;另外一方面,若是被黑客獲取到堆棧信息,也是一種安全隱患。

  因此咱們在編程過程當中,使用了不少try{   } catch{  },每當出現異常XxxException,能夠根據異常的類型,返回給客戶一個特定的異常頁面。這個返回異常的部分若是直接寫在業務代碼中也是能夠的,可是卻不是推薦的。

  Spring MVC提供了一個ExceptionResolver解析器,這個解析器能夠爲咱們作這麼一個事情:根據咱們自定義的配置,當出現某種Exception的時候,就直接跳轉到指定的頁面,不須要在邏輯代碼中進行處理。

  舉個例子:當服務端接收客戶端上傳的文件時,發現文件的大小超過了設置的最大值,此時,若是配置MultipartResolver時設置了上傳文件的最大值,那麼此時就會出現org.springframework.web.multipart.MaxUploadSizeExceededException,出現異常時,異常堆棧信息也會顯示給客戶端,此時就能夠配置下ExceptionResolver,當出現這個錯誤,就跳轉到uploadFailed.jsp中。

 

  配置ExceptionResolver解析器

  配置ExceptionResolver解析器的方式也很簡單,只須要配置一個id爲exceptionResolver的<bean>便可,class能夠是ExceptionResolver的一個實現實現類。

<!-- 配置ExceptionResolver解析器 -->
<bean id="exceptionResolver" class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
	<!-- 配置異常與跳轉頁面的對應關係 -->
	<property name="exceptionMappings">
		<props>
			<prop key="org.springframework.web.multipart.MaxUploadSizeExceededException">/uploadFailed.jsp</prop>
		</props>
	</property>
</bean>
相關文章
相關標籤/搜索