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


目錄


上傳文件的表單要求

Spring MVC實現上傳文件

需要導入的jar包

配置MultipartResolver解析器

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

Spring MVC實現文件下載

下載文件時的header設置

編寫文件下載的控制器

Spring MVC配置異常跳轉的頁面

配置異常頁面的介紹

配置ExceptionResolver解析器

 

 

 


 

 

 

上傳文件的表單要求

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

  1、action:表示要提交到哪里;

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

  3、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實現文件下載主要有兩步:

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

  2、讀取需要下載的文件,然后使用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;    那么當客戶端點擊下載鏈接時,發生的事情可能超乎預料。上面這兩個資源鏈接的文件的擴展名,擴展名指明了該文件的格式。如果沒有設置文件以附件形式下載,那么對於不同的瀏覽器,對於文件的處理方式是不同的:

  1、如果瀏覽器能夠打開或者能夠解析該類型文件,那么,文件就會直接被瀏覽器打開(注意,不是下載,不會保存到用戶的本地磁盤);

  2、如果瀏覽器不能打開或者不能解析該類型的文件,那么,瀏覽器才會將文件下載下來(保存到用戶磁盤)。

  比如,當服務器響應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>

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM