通過SpringMVC實現文件/多文件上傳與下載案例

在web開發中一般會有文件上傳的操作
一般JavaWeb開發中文件上傳使用的 Apache組織的Commons FileUpload組件
SpringMVC中使用 MultipartFile file對象接受上傳文件,必須保證 後臺參數的名稱和表單提交的文件的名稱一致

文件上傳必須條件
1.表單必須post
2.表單必須有 file 文件域
3.表單的 enctype=“multipart/form-data”

需要用到的jar包

在這裏插入圖片描述

web.xml配置
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" id="WebApp_ID" version="4.0">
 
 
 
 <!-- 設置請求參數字符編碼過濾 -->
	<filter>
		<filter-name>CharacterEncodingFilter</filter-name>
		<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
		<init-param>
			<param-name>encoding</param-name>
			<param-value>UTF-8</param-value>
		</init-param>
	</filter>	
	
	<filter-mapping>
		<filter-name>CharacterEncodingFilter</filter-name>
		<url-pattern>\/*</url-pattern>
	</filter-mapping>
 
 

 <servlet>
 	<servlet-name>MVC</servlet-name>
 	<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
 	<init-param>
 		<param-name>contextConfigLocation</param-name>
 		<param-value>classpath:springmvc.xml</param-value>
 	</init-param>
 	<load-on-startup>1</load-on-startup>
 </servlet>
 
 	<servlet-mapping>
 		<servlet-name>MVC</servlet-name>
 		<url-pattern>*.do</url-pattern>
 	</servlet-mapping>
 
</web-app>

springmvc.xml配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:mvc="http://www.springframework.org/schema/mvc"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
		
	<!-- 包掃描 -->
	<context:component-scan base-package="com.ywq.springmvc"></context:component-scan>
	
	<!-- 註解驅動 -->	
	<mvc:annotation-driven/>
	
	<!-- 配置文件上傳解析器 
		multipartResolver
		因爲文件上傳解析器是SpringMVC框架運行的非核心組件
		只有開發者使用時候才創建,一個項目中上傳文件的地方偶爾也就一兩個		
	-->
	<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
		<property name="maxUploadSize" value="#{1024*1024*5}"></property>
	</bean>
	
</beans>

後臺jsp頁面
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
後臺首頁
</body>
</html>
文件上傳jsp頁面
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
 
 <span style="color: red;">${msg}</span>
<fieldset>
		<legend>單個文件上傳</legend>
		<form action="${pageContext.request.contextPath}/upload.do" method="post" enctype="multipart/form-data">
			姓名: <input name="username"><br>
			頭像: <input type="file" name="headImg"><br>
			<button type="submit">提交</button>
		</form>
	</fieldset>
	
	
	<fieldset>
		<legend>多個文件上傳</legend>
		<form action="${pageContext.request.contextPath}/uploads.do" method="post" enctype="multipart/form-data">
			文件1: <input type="file" name="headImgs"><br>
			文件2: <input type="file" name="headImgs"><br>
			文件3: <input type="file" name="headImgs"><br>
			<button type="submit">提交</button>
		</form>
	</fieldset>

SpringMVC中使用 MultipartFile file對象接受上傳文件,必須保證 後臺方法MultipartFile 參數的名稱和表單提交的文件的名稱一致

文件上傳控制層代碼

package com.ywq.springmvc.controller;

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

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

@Controller
public class FileUploadController {
	
	
	/*
	 * 
	 * SpringMVC框架已經對文件上傳接收完成處理,是對Apache的FileUpload文件上傳組件的集成
	 * 
	 * 開發之在接收上傳的文件注入:MultipartFile即可
	 * 實現類:org.springframework.wbe.multipart.commons.CommonsMultipartFile
	 * 
	 * 注意:注入的參數名稱必須和前臺表單的名稱一致
	 * 
	 * */
	
	private List<String> mimeTypes = Arrays.asList("image/jpeg","image/png");
	
	@RequestMapping("/upload")
	public String update( String username,MultipartFile headImg,Model m ) {
		System.out.println(username);
		System.out.println(headImg);
		System.out.println(headImg.getName());//表單名稱	
		System.out.println(headImg.getOriginalFilename());//文件名稱
		System.out.println(headImg.getContentType());//獲取文件MIME類型
		
		/*
		 * 什麼是MIME文件?
		 *  計算機上所有文件都有文件類型,這個文件類型就叫做MIME類型
		 *  MIME的格式 xxxx/xxx
		 *  
		 *  常見文件MIME類型
		 *  	.jpg --->image/jpeg
		 *  	.png --->image/png
		 *  	.html --->text/html
		 *  
		 *  使用MIME可以對文件上傳的文件內容進行判斷,比如:只能上傳圖片
		 * 
		 * */
		
		//文件類型判斷
		if (!mimeTypes.contains(headImg.getContentType())) {
			m.addAttribute("msg", "文件必須是jpg或者png格式");
			return "/upload.jsp";
		}
		
		//將上傳的文件保存到服務器的某一塊磁盤位置
		//文件上傳的目錄
		File parent = new File("d:/linshi");
		if (!parent.exists()) {
			parent.mkdir(); //創建單級目錄
			//parent.mkdirs()//創建多級目錄
		}
		
		//獲取上傳的文件的後綴
		String extension = FilenameUtils.getExtension(headImg.getOriginalFilename());
		
		//創建新的文件名稱
		String newFilename = UUID.randomUUID().toString().replaceAll("-", "")+"."+extension;
		
		File dest = new File(parent, newFilename);
		
		try {
			//上傳文件
			headImg.transferTo(dest);
		} catch (IllegalStateException | IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return "/main.jsp";
	}
	
	
	
	@RequestMapping("/uploads")
	public String updates( String username,MultipartFile[] headImgs,Model m ) {
		
		//將上傳的文件保存到服務器的某一塊磁盤位置
		//文件上傳的目錄
		File parent = new File("d:/linshi");
		if (!parent.exists()) {
			parent.mkdir(); //創建單級目錄
			//parent.mkdirs()//創建多級目錄
		}
		
		for (MultipartFile headImg : headImgs) {
			//文件類型判斷
			if (!mimeTypes.contains(headImg.getContentType())) {
				m.addAttribute("msg", "文件必須是jpg或者png格式");
				return "/upload.jsp";
			}
			
			//獲取上傳的文件的後綴
			String extension = FilenameUtils.getExtension(headImg.getOriginalFilename());
			
			//創建新的文件名稱
			String newFilename = UUID.randomUUID().toString().replaceAll("-", "")+"."+extension;
			
			File dest = new File(parent, newFilename);
			
			try {
				//上傳文件
				headImg.transferTo(dest);
			} catch (IllegalStateException | IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		return "/main.jsp";
	}
}

文件下載,SpringMVC並沒有做過多的封裝,還是使用原來的下載方式

JavaWeb 開發中使用 ServletOutStream 向瀏覽器響應數據(輸出流輸出數據),就是下載文件

文件下載jsp頁面

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
	
	<h3>高清影視下載</h3>
	<a href="${pageContext.request.contextPath}/download.do?fileName=tiaoyins.mp4">調音師(生肉)</a><br>
	<a href="${pageContext.request.contextPath}/download.do?fileName=調音師.mp4">調音師(熟肉)</a><br>

文件下載控制層代碼
package com.ywq.springmvc.controller;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;

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

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

@Controller
public class DownloadController {

	/*
	 * 文件下載思路
	 * 
	 * 1.程序根據接收的文件名稱找到磁盤對應的文件,讀取內存中來(文件不能太大),形成一個輸入流
	 *
	 * 2.通過Web開發中HttpServleResponse中獲取輸出流 ServletOutputStream將輸入流響應給瀏覽器(下載)
	 * 2.1 設置Http協議響應頭,告訴瀏覽器(現在不是普通默認渲染html,而是響應附件內容(下載))
	 * 
	 * */
	@RequestMapping("/download")
	public void download(String fileName,HttpServletResponse response,HttpServletRequest request) throws IOException {
		
		System.out.println("fileName:"+fileName);
		
	//1.程序根據接收的文件名稱找到磁盤對應的文件,讀取內存中來(文件不能太大),形成一個輸入流
		InputStream inputStream = new FileInputStream("d:/linshi/"+fileName);
		
	//2.獲取輸出流
		ServletOutputStream outputStream = response.getOutputStream();
		
		/*
		 * 瀏覽器兩個標準
		 * 
		 * IE:微軟
		 * 
		 * W3C:萬維網聯盟(互聯網標準組織)
		 * 	google瀏覽器
		 * 	firefox瀏覽器
		 * 	...
		 * 
		 * 	國產瀏覽器都是基於谷歌和IE開源內核封裝一個殼子
		 * 
		 * 	文件下載的時候
		 * 	W3C響應給瀏覽器的文件名稱編碼是ISO-8859-1編碼
		 * 	需要再響應給瀏覽器之前將文件編碼轉換成ISO-8859-1編碼
		 * 
		 * 	IE
		 * 		UTF-8
		 * 
		 * */
		
		//獲取請求頭的User-Agent
		String userAgernt = request.getHeader("User-Agent");
		System.out.println(userAgernt);
		
		if (!userAgernt.contains("MSIE")) { //非IE瀏覽器
			//先將字符串轉換成字節數組
			byte[] bytes = fileName.getBytes("UTF-8");
			
			//創建新的字符串:ISO-8859-1編碼格式
			fileName = new String(bytes,"ISO-8859-1");
		}
		System.out.println("fileName:"+fileName);
		
	//2.1設置Http協議響應頭,告訴瀏覽器(現在不是普通默認渲染html,而是響應附件內容(下載))
		response.setHeader("Content-Disposition", "attachment;filename="+fileName);
		
		/*
		 * commons-io-1.4.jar 工具包中有文件各種處理工具類
		 * 
		 * IOUtile:IO輸入輸出流工具類
		 * */
		
		IOUtils.copy(inputStream, outputStream);
		
		
		
	}
	
}

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