Spring MVC 文件上传与下载
1. 单文件上传
SpringMVC 的文件上传操作底层使用的是 Apache fileupload 组件完成的,并对文件的二进制流读写进行了封装。
1、在 pom.xml 中引入文件上传组件的依赖,包括:commons-io
和 commons-fileupload
;
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.3</version>
</dependency>
2、JSP 视图层
- input 标签的 type 设置为 file;
- form 标签的 method 设置为 post(get 请求只能将文件名传给服务器);
- form 标签的 enctype 设置为 multipart/form-data(如果不设置,则只会将文件名传给服务器);
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page isELIgnored="false" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form action="/file/upload" method="post" enctype="multipart/form-data">
<input type="file" name="image"><input type="submit" value="上传图片">
</form>
<c:if test="${filepath!=null}">
<div>图片预览:</div>
<img src="${filepath}" width="50%" height="50%">
</c:if>
</body>
</html>
如果上传成功,返回当前页面,展示上传成功的图片,这里需要使用到 JSTL 标签进行判断。所以还需要在 pom.xml 文件中引入 JSTL 依赖:
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
3、业务方法,使用 MultipartFile 对象作为参数,接收前端发送过来的文件封装成对象,并完成上传操作。
package com.trainingl.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
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;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
@Controller
@RequestMapping("/file")
public class FileHandler {
@RequestMapping(value = "/upload",method = RequestMethod.POST)
public String fileUpload(@RequestParam(value = "image")MultipartFile img, HttpServletRequest request){
//getSize()方法获取文件的大小来判断是否有上传文件
if (img.getSize()>0){
//获取保存上传文件的file路径
String path = request.getServletContext().getRealPath("file");
//获取上传的文件名
String name = img.getOriginalFilename();
File file = new File(path,name);
//判断文件是否存在,如果不存在则创建
if(!file.getParentFile().exists()){
file.getParentFile().mkdirs();
}
try {
//将图片写入文件
img.transferTo(file);
//保存上传之后的文件
request.setAttribute("filepath","/file/"+name);
} catch (IOException e) {
e.printStackTrace();
}
}
return "index";
}
}
4、在 springmvc.xml 中配置上传组件;
<!-- 配置上传组件 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 处理文件名中文乱码 -->
<property name="defaultEncoding" value="utf-8"/>
</bean>
5、在 web.xml 添加如下配置,否则客户端无法访问到资源;
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.png</url-pattern>
</servlet-mapping>
6、启动 Tomcat 服务器,运行程序的结果如下:
2. 多文件上传
保持和上面统一的依赖导入(commons-io、commons-fileupload、jstl、standard)和组件配置(CommonsMultipartResolver);
1、JSP 视图层
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page isELIgnored="false" %>
<%@ taglib prefix="core" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>文件批量上传</title>
</head>
<body>
<form action="/file/uploads" method="post" enctype="multipart/form-data">
文件1:<input type="file" name="imgs"><br/>
文件2:<input type="file" name="imgs"><br/>
文件3:<input type="file" name="imgs"><br/>
<input type="submit" value="上传文件">
</form>
<core:forEach items="${files}" var="file">
<img src="${file}" alt="" width="100px">
</core:forEach>
</body>
</html>
2、业务方法,使用 MultipartFile 数组对象接收上传的多个文件对象;
@PostMapping(value = "/uploads")
public String imgsUpload(MultipartFile[] imgs,HttpServletRequest request){
//存放文件路径
List<String> files = new ArrayList<String>();
for (MultipartFile img:imgs){
if(img.getSize()>0){
//获取保存上传文件的路径
String path = request.getServletContext().getRealPath("file");
//获取上传的文件名
String name = img.getOriginalFilename();
File file = new File(path,name);
//判断文件是否存在,如果不存在则创建
if(!file.getParentFile().exists()){
file.getParentFile().mkdirs();
}
try {
img.transferTo(file);
//保存上传之后的文件
files.add("/file/"+name);
} catch (IOException e) {
e.printStackTrace();
}
}
}
request.setAttribute("files",files);
return "upload";
}
3、启动 Tomcat 服务器,运行程序;
3. 文件下载
1、JSP 视图层,使用超链接下载之前上传的图片;
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>文件下载</title>
</head>
<body>
<a href="download?fileName=1.jpg">点击下载</a>
</body>
</html>
2、业务方法
@Controller
@RequestMapping("/file")
public class FileHandler {
@GetMapping("/download")
public void downloadFile(String fileName, HttpServletRequest request, HttpServletResponse response){
if (fileName!=null){
//获取file的绝对路径
String realPath = request.getServletContext().getRealPath("file/");
File file = new File(realPath,fileName);
//二进制文件输出流
OutputStream outputStream = null;
if(file.exists()){
//设置下载完毕不打开文件
response.setContentType("application/force-download");
//设置文件名
response.setHeader("Content-Disposition","attachment;filename="+fileName);
try {
outputStream = response.getOutputStream();
//二进制流读写文件(先从服务器读)
outputStream.write(FileUtils.readFileToByteArray(file));
outputStream.flush();
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
}
3、启动 Tomcat 服务器,运行程序;
先上传一张图片资源:
点击【文件下载】超链接下载图片: