下面我会为大家详细讲解“SpringMVC教程之文件上传与下载详解”的完整攻略。
一、背景
在 web 开发中,文件的上传和下载是非常常见的操作。Spring 框架提供了相应的类和接口,可以方便地实现文件上传和下载功能。本文将结合两个实例,介绍 SpringMVC 的文件上传和下载的实现方法。
二、文件上传
2.1 概述
文件上传分为两步:
-
在表单中添加文件上传控件,用于选择要上传的文件。
-
服务器端处理文件上传请求,将文件保存到指定的位置。
2.2 简单示例
上传文件的示例代码如下。首先是前端的表单界面:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>文件上传示例</title>
</head>
<body>
<form method="post" action="/upload" enctype="multipart/form-data">
<input type="file" name="file" />
<input type="submit" value="上传" />
</form>
</body>
</html>
其中,<form>
标签中的 method
属性必须指定为 post
,action
属性对应的是文件上传请求的处理地址。
服务器端对于文件上传请求的处理,示例代码如下:
@Controller
public class FileUploadController {
@RequestMapping(value = "/upload", method = RequestMethod.POST)
public String upload(@RequestParam("file") MultipartFile file, Model model) throws IOException {
if (!file.isEmpty()) {
byte[] bytes = file.getBytes();
FileOutputStream fos = new FileOutputStream("C:/temp/" + file.getOriginalFilename());
fos.write(bytes);
fos.close();
model.addAttribute("msg", "文件上传成功!");
} else {
model.addAttribute("msg", "文件上传失败:文件为空!");
}
return "uploadResult";
}
}
该类使用 @Controller
注解声明为控制器, @RequestMapping
注解指定处理 "/upload"
请求,其中 @RequestParam("file")
注解指定上传文件的参数名为 file
。在方法体中,使用 getBytes()
方法获取文件的字节流,保存到指定的文件中。最后,通过 model
传递消息给视图,告知上传结果。其中名为 uploadResult
的视图用于展示上传结果。
至此,简单的文件上传功能已经实现了。若出现错误,报错信息将会在视图 uploadResult
中显示出来。
2.3 进阶示例
进阶的文件上传示例实现了以下几个特性:
-
使用 Spring 的表单标签库,生成包含文件上传功能的表单界面。
-
实现同时上传多个文件的功能。
-
限制上传文件的类型和大小。
先来看看前端的表单界面:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>文件上传示例</title>
</head>
<body>
<%@ taglib uri="http://www.springframework.org/tags/form" prefix="f" %>
<f:form method="post" action="/simpleUpload" commandName="myFile">
<f:input type="file" path="files" id="files" name="files" multiple="multiple" /><br />
<f:errors path="files" cssClass="error" />
<br />
<input type="submit" value="上传" />
</f:form>
</body>
</html>
在该表单界面中使用了 Spring 的表单标签库,通过 f:form
标签生成 form 表单,commandName
属性指定表单的 model 类,后续会用到。在表单中使用 f:input
标签生成文件上传控件,通过 path
属性指定上传文件的属性名(即使用 setter
方法设置这个参数)。
然后,我们需要在后端实现文件上传功能。示例代码如下:
@Controller
public class AdvancedFileUploadController {
@RequestMapping(value = "/simpleUpload", method = RequestMethod.POST)
public String simpleUpload(@ModelAttribute("myFile") MyFile myFile, BindingResult result, Model model)
throws IOException {
if (result.hasErrors()) {
model.addAttribute("msg", "上传失败:表单验证出错!");
return "advancedUploadResult";
}
List<MultipartFile> files = myFile.getFiles();
if (files.size() == 0) {
model.addAttribute("msg", "上传失败:未选择任何文件!");
return "advancedUploadResult";
}
for (MultipartFile file : files) {
if (!file.isEmpty()) {
String fileName = file.getOriginalFilename();
String fileType = fileName.substring(fileName.lastIndexOf(".") + 1, fileName.length());
if (!fileType.equalsIgnoreCase("jpg") && !fileType.equalsIgnoreCase("png")) {
model.addAttribute("msg", "上传失败:文件类型不正确!");
return "advancedUploadResult";
}
if (file.getSize() > 1024 * 1024) {
model.addAttribute("msg", "上传失败:文件大小超限!");
return "advancedUploadResult";
}
byte[] bytes = file.getBytes();
FileOutputStream fos = new FileOutputStream("C:/temp/" + fileName);
fos.write(bytes);
fos.close();
}
}
model.addAttribute("msg", "上传成功!");
return "advancedUploadResult";
}
@RequestMapping(value = "/advancedUpload", method = RequestMethod.GET)
public String showUploadForm(Model model) {
model.addAttribute("myFile", new MyFile());
return "advancedUpload";
}
}
class MyFile {
private List<MultipartFile> files;
public List<MultipartFile> getFiles() {
return files;
}
public void setFiles(List<MultipartFile> files) {
this.files = files;
}
}
其中 @ModelAttribute("myFile")
注解指定 model 的名称为 myFile
,在表单中就可以使用 myFile.files
的方式获取上传文件列表。使用 BindingResult
对上传的数据进行校验,若校验失败,将错误信息展示在视图中。调用 getFiles()
方法按顺序获取到上传文件列表,遍历其中文件:
在遍历的过程中,首先获取文件名,并从文件名中获取文件类型。然后判断文件类型和大小是否符合要求,不符合则返回错误消息。最后,使用 getBytes()
方法获取文件的字节流,保存到指定的文件中。
在实现文件上传功能中,我们还可以结合第三方组件 commons-fileupload
来解析上传文件流。在 Spring 中,只需要在配置文件中引入相关依赖,然后使用 CommonsMultipartResolver
即可自动将文件上传流转化为 MultipartFile,方便操作。
三、文件下载
3.1 概述
文件下载功能比文件上传要简单得多。在 Spring 中,可以通过在响应头中设置 Content-Disposition
头,浏览器就会自动弹出下载框,提示用户下载文件。同时,还需要将文件的字节流写入响应体中。
3.2 示例
实现文件下载的示例代码如下:
@Controller
public class FileDownloadController {
@RequestMapping(value = "/download", method = RequestMethod.GET)
public void download(HttpServletRequest request, HttpServletResponse response) throws Exception {
String fileName = "myFile.jpg";
String filePath = "C:/temp/" + fileName;
File file = new File(filePath);
if (file.exists()) {
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
FileInputStream fis = new FileInputStream(file);
OutputStream os = response.getOutputStream();
byte[] buffer = new byte[1024];
int len = 0;
while ((len = fis.read(buffer)) > 0) {
os.write(buffer, 0, len);
}
os.flush();
os.close();
fis.close();
} else {
response.getWriter().write("文件不存在!");
}
}
}
文件下载请求的处理函数为 download()
,在其中通过 Content-Disposition
头和响应的输出流向浏览器返回文件内容,实现文件下载功能。
四、总结
本文介绍了如何使用 SpringMVC 实现文件上传和下载功能。对于文件上传功能,我们讲解了基础示例和进阶示例,通过表单标签库的使用,限制文件上传的大小和类型,同时支持多个文件上传。对于文件下载功能,我们通过设置响应头和响应体中的字节流向浏览器返回文件内容,实现了文件下载功能。
以上便是“SpringMVC教程之文件上传与下载详解”的完整攻略。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:SpringMVC教程之文件上传与下载详解 - Python技术站