SpringMVC實現(xiàn)文件的上傳和下載實例代碼
前些天一位江蘇經(jīng)貿(mào)的學(xué)弟跟我留言問了我這樣一個問題:“用什么技術(shù)來實現(xiàn)一般網(wǎng)頁上文件的上傳和下載?是框架還是Java中的IO流”。我回復(fù)他說:“使用SpringMVC框架可以做到這一點,因為SpringMVC為文件的上傳提供了直接的支持,但需要依賴Apache提供Commons FileUpload組件jar包?!辫b于這個問題,我上網(wǎng)也百度了一下,網(wǎng)上很多都是介紹的使用IO流來實現(xiàn)文件的上傳和下載,也有說到框架的,但介紹的并不是很完整,今天小錢將和大家介紹使用SpringMVC框架來實現(xiàn)文件的上傳和下載,本文將做一個項目案例來完整的使用SpringMVC框架實現(xiàn)文件的上傳和下載。
文件上傳
文件上傳是項目開發(fā)中最常見的功能。為了能上傳文件,必須將表單的method設(shè)置為POST,并將enctype設(shè)置為multipart/form-data。只有在這樣的情況下,瀏覽器才會把用戶選擇的文件以二進(jìn)制數(shù)據(jù)發(fā)送給服務(wù)器。
一旦設(shè)置了enctype為multipart/form-data,瀏覽器即會采用二進(jìn)制流的方式來處理表單數(shù)據(jù),而對于文件上傳的處理則涉及在服務(wù)器端解析原始的HTTP響應(yīng)。在2003年,Apache Software Foundation發(fā)布了開源的Commons FileUpload組件,其很快成為Servlet/JSP程序員上傳文件的最佳選擇。
Servlet3.0規(guī)范已經(jīng)提供方法來處理文件上傳,但這種上傳需要在Servlet中完成。而SpringMVC則提供了更簡單的封裝。
SpringMVC為文件上傳提供了直接的支持,這種支持是用即插即用的MultipartResolver實現(xiàn)的。SpringMVC使用Apache Commons FileUpload技術(shù)實現(xiàn)了一個MultipartResolver實現(xiàn)類:CommonsMultipartResolver。因此,SpringMVC的文件上傳還需要依賴Apache Commons FileUpload的組件。
本項目作為測試案例,在此我就不創(chuàng)建Maven項目了,我直接創(chuàng)建的是一個Dynamic Web Project(動態(tài)的web項目),采用Tomcat 8作為web服務(wù)器,我們需要在項目中引入以下jar包,如下圖:

下面我們在WebContent/WEB-INF下創(chuàng)建一個content文件夾,用于放文件的上傳、下載等jsp文件,下面我們創(chuàng)建uploadForm.jsp文件,演示SpringMVC的文件上傳:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>文件上傳</title>
</head>
<body>
<h2>文件上傳</h2>
<form action="upload" enctype="multipart/form-data" method="post">
<table>
<tr>
<td>文件描述:</td>
<td><input type="text" name="description"></td>
</tr>
<tr>
<td>請選擇文件:</td>
<td><input type="file" name="file"></td>
</tr>
<tr>
<td><input type="submit" value="上傳"></td>
</tr>
</table>
</form>
</body>
</html>
負(fù)責(zé)上傳文件的表單和一般表單有一些區(qū)別,負(fù)責(zé)上傳文件的表單的編碼類型必須是“multipart/form-data”。
我們再src下創(chuàng)建一個包“cn.edu.jseti.controller”,然后創(chuàng)建一個FileUploadController類,用于實現(xiàn)文件的上傳和下載功能。以下是負(fù)責(zé)上傳文件的表單功能代碼:
//上傳文件會自動綁定到MultipartFile中
@RequestMapping(value="/upload",method=RequestMethod.POST)
public String upload(HttpServletRequest request,
@RequestParam("description") String description,
@RequestParam("file") MultipartFile file) throws Exception {
System.out.println(description);
//如果文件不為空,寫入上傳路徑
if(!file.isEmpty()) {
//上傳文件路徑
String path = request.getServletContext().getRealPath("/images/");
//上傳文件名
String filename = file.getOriginalFilename();
File filepath = new File(path,filename);
//判斷路徑是否存在,如果不存在就創(chuàng)建一個
if (!filepath.getParentFile().exists()) {
filepath.getParentFile().mkdirs();
}
//將上傳文件保存到一個目標(biāo)文件當(dāng)中
file.transferTo(new File(path + File.separator + filename));
return "success";
} else {
return "error";
}
}
SpringMVC會將上傳的文件綁定到MultipartFile對象中。MultipartFile提供了獲取上傳文件內(nèi)容、文件名等方法。通過transferTo()方法還可以將文件存儲到硬件中,MultipartFile對象中的常用方法如下:
- byte[] getBytes():獲取文件數(shù)據(jù)
- String getContentType[]:獲取文件MIME類型,如image/jpeg等
- InputStream getInputStream():獲取文件流
- String getName():獲取表單中文件組件的名字
- String getOriginalFilename():獲取上傳文件的原名
- Long getSize():獲取文件的字節(jié)大小,單位為byte
- boolean isEmpty():是否有上傳文件
- void transferTo(File dest):將上傳文件保存到一個目錄文件中
SpringMVC上下文中默認(rèn)沒有裝配MultipartResolver,因此默認(rèn)情況下其不能處理文件上傳工作。如果想使用spring的文件上傳功能,則需要在上下文中配置MultipartResolver。在springmvc-config.xml進(jìn)行配置文件如下:
<?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:p="http://www.springframework.org/schema/p"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.2.xsd">
<!-- spring可以自動去掃描base-pack下面的包或者子包下面的java文件,
如果掃描到有Spring的相關(guān)注解的類,則把這些類注冊為Spring的bean -->
<context:component-scan base-package="cn.edu.jseti.controller"/>
<!-- 視圖解析器 -->
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 前綴 -->
<property name="prefix">
<value>/WEB-INF/content/</value>
</property>
<!-- 后綴 -->
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 上傳文件大小上限,單位為字節(jié)(10MB) -->
<property name="maxUploadSize">
<value>10485760</value>
</property>
<!-- 請求的編碼格式,必須和jSP的pageEncoding屬性一致,以便正確讀取表單的內(nèi)容,默認(rèn)為ISO-8859-1 -->
<property name="defaultEncoding">
<value>UTF-8</value>
</property>
</bean>
</beans>
部署FileUpload這個Web應(yīng)用,在瀏覽器中輸入如下URL來測試應(yīng)用: http://localhost:8088/FileUpload/uploadForm
輸入文件描述信息并選擇上傳文件,如下圖:
點上傳按鈕,這是已將上傳的文件通過二進(jìn)制保存到web服務(wù)器上去了,如下圖:

使用對象接收上傳文件
上面我們通過案例演示了SpringMVC上傳文件,接下來,我們演示使用對象接收上傳文件。
在實際項目的開發(fā)中,很多時候上傳的文件會作為對象的屬性被保存。SpringMVC的處理也非常的簡單。
下面我們在content文件夾創(chuàng)建registerForm.jsp文件,演示接收文件上傳:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>用戶注冊</title>
</head>
<body>
<h2>用戶注冊</h2>
<form action="register" enctype="multipart/form-data" method="post">
<table>
<tr>
<td>用戶名:</td>
<td><input type="text" name="username"></td>
</tr>
<tr>
<td>請上傳頭像:</td>
<td><input type="file" name="image"></td>
</tr>
<tr>
<td><input type="submit" value="注冊"></td>
</tr>
</table>
</form>
</body>
</html>
我們在src下面創(chuàng)建一個名叫“cn.edu.jseti.domain”包,然后再創(chuàng)建一個User類,必須要實現(xiàn)序列化接口,如下案例代碼:
package cn.edu.jseti.domain;
import java.io.Serializable;
import org.springframework.web.multipart.MultipartFile;
/**
* 博客:http://blog.csdn.net/qian_ch
* @author Cody
* @version V1.0
*/
//域?qū)ο螅瑢崿F(xiàn)序列化接口
public class User implements Serializable{
private String username;
private MultipartFile image;
public User() {
super();
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public MultipartFile getImage() {
return image;
}
public void setImage(MultipartFile image) {
this.image = image;
}
}
我們在剛才創(chuàng)建的FileUploadController類繼續(xù)寫用于接收文件的上傳和下載功能。以下是負(fù)責(zé)接收文件的表單功能代碼:
@RequestMapping(value="/register")
public String register(HttpServletRequest request,
@ModelAttribute User user,
Model model) throws Exception {
System.out.println(user.getUsername());
//如果文件不為空,寫入上傳路徑
if(!user.getImage().isEmpty()) {
//上傳文件路徑
String path = request.getServletContext().getRealPath("/images/");
//上傳文件名
String filename = user.getImage().getOriginalFilename();
File filepath = new File(path,filename);
//判斷路徑是否存在,如果不存在就創(chuàng)建一個
if (!filepath.getParentFile().exists()) {
filepath.getParentFile().mkdirs();
}
//將上傳文件保存到一個目標(biāo)文件當(dāng)中
user.getImage().transferTo(new File(path + File.separator + filename));
//將用戶添加到model
model.addAttribute("user", user);
return "userInfo";
} else {
return "error";
}
}
在content文件夾下創(chuàng)建userInfo.jsp文件,該頁面主要是文件的下載頁面,如下jsp代碼:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>文件下載</title>
</head>
<body>
<h3>文件下載</h3>
<a href="download?filename=${requestScope.user.image.originalFilename}" rel="external nofollow" >
${requestScope.user.image.originalFilename }
</a>
</body>
</html>
在瀏覽器中輸入如下URL來測試應(yīng)用: http://localhost:8088/FileUpload/registerForm
輸入用戶名并上傳剛才上傳的文件。如下圖:
單擊“注冊”按鈕上傳文件,然后就會跳轉(zhuǎn)到下載頁面。如下圖:

文件下載
上面我們通過案例演示了使用對象接收上傳文件,接下來,我們演示SpringMVC的下載文件。
文件下載比較簡單,直接在頁面給出了一個超鏈接,該鏈接href的屬性等于要下載文件的文件名,就可以實現(xiàn)文件下載了。但是如果該文件的文件名為中文文件名,在某些早起的瀏覽器上就會導(dǎo)致下載失敗;如果使用最新的Firefox、Chrome、Opera、Safari則都可以正常下載文件名為中文的文件了。
SpringMVC提供了一個ResponseEntity類型,使用它可以很方便地定義返回的HttpHeaders和HttpStatus。以下代碼演示文件的下載功能:
@RequestMapping(value="/download")
public ResponseEntity<byte[]> download(HttpServletRequest request,
@RequestParam("filename") String filename,
Model model)throws Exception {
//下載文件路徑
String path = request.getServletContext().getRealPath("/images/");
File file = new File(path + File.separator + filename);
HttpHeaders headers = new HttpHeaders();
//下載顯示的文件名,解決中文名稱亂碼問題
String downloadFielName = new String(filename.getBytes("UTF-8"),"iso-8859-1");
//通知瀏覽器以attachment(下載方式)打開圖片
headers.setContentDispositionFormData("attachment", downloadFielName);
//application/octet-stream : 二進(jìn)制流數(shù)據(jù)(最常見的文件下載)。
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file),
headers, HttpStatus.CREATED);
}
download處理方法接收頁面?zhèn)鬟f的文件名filename后,使用Apache Commons FileUpload組件的FileUtils讀取項目的上傳文件,并將其構(gòu)建成ResponseEntity對象返回客戶端下載。
使用ResponseEntity對象,可以很方便的定義返回的HttpHeaders和HttpStatus。上面代碼中的MediaType,代表的是Internet Media Type,即互聯(lián)網(wǎng)媒體類型,也叫做MIME類型。在Http協(xié)議消息頭中,使用Content-Type來表示具體請求中的媒體類型信息。HttpStatus類型代表的是Http協(xié)議中的狀態(tài)。有關(guān)MediaType和HttpStatus類可以參考SpringMVC的API文檔。
點擊下載頁面的超鏈接,顯示文件正在下載,如下圖所示:

單擊“瀏覽”按鈕,可以選擇下載文件的保存路徑,然后單擊“確定”按鈕,文件就會順利的下載并保存。
本文中的一些功能案例代碼和配置文件不是很完整,下面附上完整代碼:
FileUploadController類完整的代碼如下:
package cn.edu.jseti.controller;
import java.io.File;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.io.FileUtils;
import cn.edu.jseti.domain.User;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
/**
* @author Cody
* @version V1.0
*/
@Controller
public class FileUploadController {
@RequestMapping(value="/{formName}")
public String loginForm(@PathVariable String formName) {
// 動態(tài)跳轉(zhuǎn)頁面
return formName;
}
//上傳文件會自動綁定到MultipartFile中
@RequestMapping(value="/upload",method=RequestMethod.POST)
public String upload(HttpServletRequest request,
@RequestParam("description") String description,
@RequestParam("file") MultipartFile file) throws Exception {
System.out.println(description);
//如果文件不為空,寫入上傳路徑
if(!file.isEmpty()) {
//上傳文件路徑
String path = request.getServletContext().getRealPath("/images/");
//上傳文件名
String filename = file.getOriginalFilename();
File filepath = new File(path,filename);
//判斷路徑是否存在,如果不存在就創(chuàng)建一個
if (!filepath.getParentFile().exists()) {
filepath.getParentFile().mkdirs();
}
//將上傳文件保存到一個目標(biāo)文件當(dāng)中
file.transferTo(new File(path + File.separator + filename));
return "success";
} else {
return "error";
}
}
@RequestMapping(value="/register")
public String register(HttpServletRequest request,
@ModelAttribute User user,
Model model) throws Exception {
System.out.println(user.getUsername());
//如果文件不為空,寫入上傳路徑
if(!user.getImage().isEmpty()) {
//上傳文件路徑
String path = request.getServletContext().getRealPath("/images/");
//上傳文件名
String filename = user.getImage().getOriginalFilename();
File filepath = new File(path,filename);
//判斷路徑是否存在,如果不存在就創(chuàng)建一個
if (!filepath.getParentFile().exists()) {
filepath.getParentFile().mkdirs();
}
//將上傳文件保存到一個目標(biāo)文件當(dāng)中
user.getImage().transferTo(new File(path + File.separator + filename));
//將用戶添加到model
model.addAttribute("user", user);
return "userInfo";
} else {
return "error";
}
}
@RequestMapping(value="/download")
public ResponseEntity<byte[]> download(HttpServletRequest request,
@RequestParam("filename") String filename,
Model model)throws Exception {
//下載文件路徑
String path = request.getServletContext().getRealPath("/images/");
File file = new File(path + File.separator + filename);
HttpHeaders headers = new HttpHeaders();
//下載顯示的文件名,解決中文名稱亂碼問題
String downloadFielName = new String(filename.getBytes("UTF-8"),"iso-8859-1");
//通知瀏覽器以attachment(下載方式)打開圖片
headers.setContentDispositionFormData("attachment", downloadFielName);
//application/octet-stream : 二進(jìn)制流數(shù)據(jù)(最常見的文件下載)。
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file),
headers, HttpStatus.CREATED);
}
}
文件上傳成功的jsp代碼:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>測試文件上傳</title> </head> <body> 恭喜,您的上傳文件成功! </body> </html>
文件上傳失敗的jsp代碼:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>測試文件上傳</title> </head> <body> 上傳文件失敗! </body> </html>
web.xml的配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<display-name>MultipartFileTest</display-name>
<!-- 定義Spring MVC的前端控制器 -->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/springmvc-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- 讓Spring MVC的前端控制器攔截所有請求 -->
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!-- 編碼過濾器 -->
<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>
</web-app>
OK,以上就是完整的使用SpringMVC框架實現(xiàn)了文件的上傳和下載。本中所有的案例都是本人親自測試,如有寫的不對,歡迎朋友們留言一起交流,謝謝!
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- SpringMVC+Ajax實現(xiàn)文件批量上傳和下載功能實例代碼
- MyBatis與SpringMVC相結(jié)合實現(xiàn)文件上傳、下載功能
- springMVC配置環(huán)境實現(xiàn)文件上傳和下載
- 在SpringMVC框架下實現(xiàn)文件的上傳和下載示例
- SpringMVC下實現(xiàn)Excel文件上傳下載
- SpringMVC框架實現(xiàn)圖片上傳與下載
- SpringMVC實現(xiàn)文件上傳和下載功能
- SpringMVC實現(xiàn)文件上傳和下載的工具類
- SpringMvc3+extjs4實現(xiàn)上傳與下載功能
- SpringMVC實現(xiàn)上傳下載文件
相關(guān)文章
30分鐘入門Java8之默認(rèn)方法和靜態(tài)接口方法學(xué)習(xí)
這篇文章主要介紹了30分鐘入門Java8之默認(rèn)方法和靜態(tài)接口方法學(xué)習(xí),詳細(xì)介紹了默認(rèn)方法和接口,有興趣的可以了解一下。2017-04-04
java使用短信設(shè)備發(fā)送sms短信的示例(java發(fā)送短信)
這篇文章主要介紹了java使用短信設(shè)備發(fā)送sms短信的示例(java發(fā)送短信),需要的朋友可以參考下2014-04-04
Java實現(xiàn)bmp和jpeg圖片格式互轉(zhuǎn)
本文主要介紹了Java實現(xiàn)bmp和jpeg圖片格式互轉(zhuǎn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-04-04
使用idea遠(yuǎn)程調(diào)試jar包的配置過程
這篇文章主要介紹了使用idea遠(yuǎn)程調(diào)試jar包的配置過程,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-09-09
SpringBoot整合SpringSecurityOauth2實現(xiàn)鑒權(quán)動態(tài)權(quán)限問題
這篇文章主要介紹了SpringBoot整合SpringSecurityOauth2實現(xiàn)鑒權(quán)-動態(tài)權(quán)限,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-06-06

