SpringMVC中文件的上传和下载
文件上传
文件的上传和下载都是项目开发中最常用的功能,例如头像的上传,图片的下载,附件文件的上传和下载等等
文件上传的概述
多数文件上传都是通过表单的形式提交给后台服务器的,因此要实现文件的上传功能,就需要提供一个文件上传的表单,并且该表单应该满足以下三个条件
- form表单的
method
属性设置为post
- form表单的
enctype
属性设置为multipart/form-data
- 提供input标签的文件上传输入框
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>文件上传</title>
</head>
<body>
<form action="update" method="post" enctype="multipart/form-data">
<input type="file" name="fileName" multiple/>
<input type="submit" value="文件上传">
</form>
</body>
</html>
注意,其中的multiple
属性是HTML5中新增属性,如果选择了该属性,那么可以同时选择多个文件进行上传,即实现了多文件的上传
当客户端form表单的enctype
属性为multipart/form-data
的时候,浏览器就会采用二进制流的形式来处理表单数据,服务器端就会对文件上传的请求进行解析处理,SpringMVC对文件上传提供了直接的支持,这种支持是通过MUltipartResolver
(多部件解析器)对象实现的
其中MUltipartResolver
是一个借口对象,需要通过它的实现类CommonsMUltipartResolver
来完成文件的上传工作,我们可以在配置文件中定义MUltipartResolver
接口的Bean来实现接口
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!--设置请求编码格式,必须和JSP中的 pageEncoding属性一致,默认为ISO-8859-1-->
<property name="defaultEncoding" value="UTF-8"/>
<!--设置允许上传文件的最大值(2M),单位为字节-->
<property name="maxUploadSize" value="2097152"/>
</bean>
其中property对应表如下
属性名 | 解释 |
---|---|
maxUploadSize | 上传文件的最大长度,其中单位为字节 |
maxUploadSizePerFile | 跟maxUploadSize差不多,不过maxUploadSizePerFile是限制每个上传文件的大小,而maxUploadSize是限制总的上传文件大小。 |
uploadTempDir | 设置上传文件时的临时目录,默认是Servlet容器的临时目录。 |
defaultEncoding | 表示用来解析request请求的默认编码格式,当没有指定的时候根据Servlet规范会使用默认值ISO-8859-1。当request自己指明了它的编码格式的时候就会忽略这里指定的defaultEncoding。 |
maxInMemorySize | 设置在文件上传时允许写到内存中的最大值,以字节为单位计算,默认是10240。 |
resolveLazily | 为true时,启用推迟文件解析,以便在UploadAction中捕获文件大小异常。 |
支持包的引入
本项目构建采用的是Maven,所以可以在pom.xml文件中引入如下配置
<!-- 上传组件包 -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.9</version>
</dependency>
实现简单的文件上传
这个时候我们可以通过简单的修改,来进行我们程序的验证,首先我们应该修改我们的JSP文件
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>文件上传</title>
</head>
<body>
<form action="/upLoadFile" method="post" enctype="multipart/form-data">
<input type="file" name="fileName" multiple/>
<input type="submit" value="文件上传">
上传是否成功:${msg}
</form>
</body>
</html>
我们可以看到,我们在form标签中新加入了一行${msg}
,这里是进行上传返回信息的显示的,之后我们在我们的controller包中新建一个FileController
类
package eendtech.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
/**
* @ author Seale
* @ Description: 文件上传
* @ QQ:1801157108
* @ Date 2019/4/14 14:51
*/
@Controller@RequestMapping(value = "/files")
public class FileController {
@RequestMapping("/file")
public String showFileJsp(){
return "views/file.jsp";
}
@RequestMapping("/upLoadFile")
public String handleFormUpload(@RequestParam("fileName") MultipartFile file,Model model){
if (!file.isEmpty()){
model.addAttribute("msg","success");
return "views/file.jsp";
}
model.addAttribute("msg","failed");
return "views/file.jsp";
}
}
在这里我需要说明一下,MultipartFile
接口类型的参数file,上传到程序中的文件就是被封装到该参数当中的,这个接口中提供了获取上传文件、文件名等方法,这些方法及其说明如下
方法 | 说明 |
---|---|
String getName() | 获取多部件form表单的参数名称 |
String getOriginalFilename() | 获取上传文件的初始化名 |
String getContentType() | 获取文件内容的类型 |
boolean isEmpty() | 是否为空 |
long getSize() | 取得文件的大小,单位是字节 |
byte[] getBytes() throws IOException | 以字节数组的形式返回文件的内容,如果文件为空则抛出IO异常 |
InputStream getInputStream() throws IOException | 读取文件的内容返回一个inputStream流 |
void transferTo(File dest) throws IOException, IllegalStateException | 将上传文件保存到目标目录下 |
运行结果
比较完整的上传例子
进行修改
我们在简单案例的基础上进行修改,模拟一个网站的真实上传头像的案例
修改我们的JSP文件
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>文件上传</title>
<script>
function checkUpload() {
var name = document.getElementById("name").value;
var file = document.getElementById("file").value;
if (name == ""){
alert("请填写上传人");
return false;
}
if (file.length==0 || file==""){
alert("请选择你要上传的文件");
return false;
}
return true;
}
</script>
</head>
<body>
<form action="${pageContext.request.contextPath}/files/upLoadFileForFinal" method="post" enctype="multipart/form-data" onsubmit="return checkUpload()">
<input id="name" type="text" name="name" placeholder="上传人的姓名"> <br>
<input id="file" type="file" name="fileName" multiple/>
<input type="submit" value="文件上传">
上传是否成功:${msg}
</form>
</body>
</html>
修改我们的controller文件
package eendtech.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
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;
import java.util.List;
import java.util.UUID;
/**
* @ author Seale
* @ Description: 文件上传
* @ QQ:1801157108
* @ Date 2019/4/14 14:51
*/
@Controller@RequestMapping(value = "/files")
public class FileController {
@RequestMapping("/file")
public String showFileJsp(){
return "views/file.jsp";
}
@RequestMapping("/upLoadFile")
public String handleFormUpload(@RequestParam("fileName") MultipartFile file,Model model){
if (!file.isEmpty()){
model.addAttribute("msg","success");
return "views/file.jsp";
}
model.addAttribute("msg","failed");
return "views/file.jsp";
}
@RequestMapping("/upLoadFileForFinal")
public String handleFormUploadForFinal(@RequestParam("name") String name
, @RequestParam("fileName") List<MultipartFile> fileList
, Model model, HttpServletRequest request){
//判断所厂商的文件是否存在
if (!fileList.isEmpty() && fileList.size() > 0){
//循环输出上传的文件
for (MultipartFile file :fileList) {
//获取上传文件的原始名称
String originalFileName = file.getOriginalFilename();
System.out.println("当前文件的名称:"+originalFileName);
//设置上传文件的保存地址
String dirPath = request.getServletContext().getRealPath("/upLoad/");
File filePath = new File(dirPath);
System.out.println("当前文件的保存地址:"+dirPath);
System.out.println("--------------------------");
if (!filePath.exists()){
//mkdirs会自动建立多级目录;mkdir只能建立一级目录,如果目录中包含多级目录,且当前目录不存在则返回false
filePath.mkdirs();
}
//使用UUID重新命名上传的文件名称(上传人_uuid_原始名称)
String newFileName = name+"_"+ UUID.randomUUID()+"_"+originalFileName;
try {
//使用MultipartFile接口的方法完成文件上传到指定目录
file.transferTo(new File(dirPath+newFileName));
} catch (IOException e) {
e.printStackTrace();
model.addAttribute("msg","上传失败");
return "views/file.jsp";
}
}
model.addAttribute("msg","上传成功");
return "views/file.jsp";
}else{
model.addAttribute("msg","上传失败");
return "views/file.jsp";
}
}
}
4 comments
最近 java 学习没什么动力了(´இ皿இ`)
尝试着做个小项目,边做边学,了解自己差哪些东西,有目标的学,就会有动力了!
不懂帮顶……
好滴,感谢!!!!