SpringMVC 文件上传和下载
1、文件上传
在Spring MVC中实现文件上传十分方便,它为文件上传提供了直接的支持,即MultipartResolver(多部件解析器)接口。MultipartResolver用于处理上传请求,将上传请求包装成可以直接获取文件的数据,从而方便操作。它有两个实现类:
- StandardServletMultipartResolver
- CommonsMultipartResolver
1.1、单文件上传
下面使用CommonsMultipartResolver实现单文件的上传功能
(1) 下载并添加jar包,访问 http://commons.apache.org/proper/,
下载commons-fileupload-1.3.3.jar和commons-io-2.6.jar。
(2) 在Spring MVC配置文件中配置CommonsMultipartResolver类
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:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
">
<!-- 配置自动扫描的包 -->
<context:component-scan base-package="com.springmvc"/>
<!-- 自动注册处理器映射器和处理器适配器 -->
<mvc:annotation-driven/>
<!-- 配置视图解析器,将控制器方法返回的逻辑视图解析为物理视图 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/ch10/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
<!-- 如果不想经过控制器类的处理方法直接转发到页面,可以通过mvc:view-controller元素来实现 -->
<mvc:view-controller path="/success" view-name="success"/>
<mvc:view-controller path="/index" view-name="index"/>
<bean class="org.springframework.web.servlet.view.BeanNameViewResolver">
<property name="order" value="50"></property>
</bean>
<mvc:default-servlet-handler/>
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 上传文件的最大尺寸为1MB -->
<property name="maxUploadSize" value="1048576"/>
<!-- 字符编码 -->
<property name="defaultEncoding" value="UTF-8"/>
</bean>
</beans>
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_3_1.xsd"
id="WebApp_ID" version="3.1">
<!-- 编码过滤器 -->
<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>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 配置springmvc的前端控制器DispatcherServlet -->
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 初始化参数,配置Spring MVC配置文件的位置和名称 -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
<!-- 表示容器在启动时,立即加载 DispatcherServlet-->
<load-on-startup>1</load-on-startup>
</servlet>
<!-- 让Spring MVC的前端控制器拦截所有请求 -->
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
(3) 在ch10文件夹中新建index.jsp页面,并在该页面上创建一个表单,用于上传文件。提交表单后,以POST方式提交到一个名为“/fileUpload”的请求中。新建success.jsp页面,添加用于访问保存到request中的fileUrl值。
index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>文件上传</title>
</head>
<body>
<form method="post" enctype="multipart/form-data" action="../fileUpload">
选择文件:<input type="file" name="file"/><br/><br/>
<input type="submit" value="上传"/><br/><br/>
</form>
</body>
</html>
success.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>文件上传</title>
</head>
<body>
文件上传成功!<br/>
上传文件的路径:${requestScope.fileUrl }
</body>
</html>
(4) 在com.springmvc.controller包中新建FileUploadController类,并在其中添加方法fileUpload,处理文件上传。
package com.springmvc.controller;
import java.io.File;
import javax.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
@Controller
public class FileUploadController {
@RequestMapping(value="/fileUpload")
public String fileUpload(@RequestParam(value="file",required=false)MultipartFile file,
HttpServletRequest request,ModelMap modelMap){
//服务器端upload文件夹物理路径
String path=request.getSession().getServletContext().getRealPath("upload");
//获取文件名
String fileName=file.getOriginalFilename();
//实例化一个file对象,表示目标文件,包含物理路径
File targetFile=new File(path,fileName);
if(!targetFile.exists()) {
//创建文件
targetFile.mkdirs();
}
try {
//将上传文件写到服务器上的指定文件
file.transferTo(targetFile);
}catch(Exception e) {
e.printStackTrace();
}
modelMap.put("fileUrl", request.getContextPath()+"/upload/"+fileName);
return "success";
}
}
(5) 部署springmvc-5,启动Tomcat,浏览http://localhost:8080/springmvc-5/ch10/index.jsp页面。
选择文件上传
查看上传文件
1.2、多文件上传
如果想通过浏览文件时,一次选择多个文件上传,可通过对方法参数中参数设置为@RequestParam(“files”) MultipartFile[] files的数组形式,这样可提交多个文件。
随着HTML 5的广泛应用,可利用移动端HTML 5的特性,一个input一次性选择多张图片的选择方式以前端设计为主,下面来介绍HTML 5的方式实现多文件上传,过程如下:
(1) 在springmvc-5项目的ch10的文件中,新建fileUpload.jsp,新建error.jsp页面,提示“文件上传失败,请重新上传!”。
fileUpload.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>利用HTML5实现多文件上传</title>
</head>
<body>
<form method="post" enctype="multipart/form-data" action="../upload">
文件描述:<input type="text" name="description"/><br/><br/>
<!-- 多文件选择属性multiple="multiple" -->
选择文件:<input type="file" name="files" multiple="multiple"/><br/><br/>
<input type="submit" value="上传"/><br/><br/>
</form>
</body>
</html>
error.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>文件上传失败</title>
</head>
<body>
文件上传失败,请重新上传!<br/>
</body>
</html>
(2) 在控制器类FileUploadController中,添加upload()方法。
@RequestMapping(value="/upload")
public String upload(@RequestParam(value="description") String description,
@RequestParam(value="files",required=false) List<MultipartFile> files,
HttpServletRequest request){
//判断文件上传是否存在
if(!files.isEmpty()&&files.size()>0) {
//循环输出上传文件
for(MultipartFile file:files) {
//获取上传的原始文件名称
String originalFileName=file.getOriginalFilename();
//获取上传文件的保存地址目录
String dirPath=request.getServletContext().getRealPath("/upload/");
File filePath=new File(dirPath);
//如果保存的文件的地址不存在,就先创建目录
if(!filePath.exists()) {
filePath.mkdirs();
}
//使用uuid重命名上传的新文件名(文件描述_uuid_原始文件名称)
String newFileName=description+"_"+UUID.randomUUID()+"_"+originalFileName;
try {
file.transferTo(new File(dirPath+newFileName));
}catch(Exception e) {
e.printStackTrace();
return "error";
}
}
return "success";
}
return "error";
}
(3) 重启Tomcat,浏览http://localhost:8080/springmvc-5/ch10/fileUpload.jsp 地址。
在上传页面中,填入文件描述,单击浏览按钮,选择所要上传的文件,单击“上传”按钮。
查看文件
2、文件下载
文件下载就是将文件服务器中的文件下载到本机上,相对比较简单,直接在页面给出了一个超链接,该链接href的属性等于要下载文件的文件名,就可以实现文件下载了。但是如果该文件的文件名为中文文件名,在某些早起的浏览器上就会导致下载失败;如果使用最新的Firefox、Chrome等浏览器则都可以正常下载文件名为中文的文件了。修改上小节单文件上传的示例,实现文件下载,步骤如下:
(1) 修改FileUploadController类中的fileUpload()方法。
@RequestMapping(value="/fileUpload")
public String fileUpload(@RequestParam(value="file",required=false)MultipartFile file,
HttpServletRequest request,ModelMap modelMap){
//服务器端upload文件夹物理路径
String path=request.getSession().getServletContext().getRealPath("upload");
//获取文件名
String fileName=file.getOriginalFilename();
//实例化一个file对象,表示目标文件,包含物理路径
File targetFile=new File(path,fileName);
if(!targetFile.exists()) {
//创建文件
targetFile.mkdirs();
}
try {
//将上传文件写到服务器上的指定文件
file.transferTo(targetFile);
}catch(Exception e) {
e.printStackTrace();
}
modelMap.put("fileUrl", request.getContextPath()+"/upload/"+fileName);
modelMap.put("fileName",fileName);
return "success";
}
(2) 修改success.jsp页面,添加一个文件下载的超链接。
<a href="fileDownLoad?fileName=${requestScope.fileName }">${requestScope.fileName }</a>
(3) 在后台FileUploadController类中,添加fileDownload()的方法,并进行相应的映射。
@RequestMapping(value="/fileDownLoad")
public ResponseEntity<byte[]> fileDownLoad(HttpServletRequest request,
@RequestParam(value="fileName") String fileName,Model model) throws Exception{
//下载文件路径
String path=request.getServletContext().getRealPath("/upload/");
//创建文件对象
File file=new File(path+File.separator+fileName);
//设置响应头
HttpHeaders headers=new HttpHeaders();
//下载显示的文件名,解决中文名乱码问题
String downLoadFileName=new String(fileName.getBytes("UTF-8"),"ISO8859-1");
//通知浏览器以下载方式(attachment)打开文件
headers.setContentDispositionFormData("attachment",downLoadFileName);
//定义以二进制流的形式下载返回的文件数据
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
//使用SpringMVC框架的ResponseEntity封装返回的下载数据
byte[] bytes=FileUtils.readFileToByteArray(file);
return new ResponseEntity<byte[]>(bytes,headers,HttpStatus.CREATED);
}
(4) 重启Tomcat,浏览http://localhost:8080/springmvc-5/ch10/
index.jsp 地址,上传文件成功后,在页面上进行下载。