1. 文件上传
1.1 前端注意事项
文件上传操作,前端的表单项需要如下三项设置:
(1)input标签的type属性应设置为file,并且注意不要在input标签中设置value属性,因为这可能导致文件上传不成功;
(2)请求方式为 method="post" ;
(3)enctype="multipart/form-data"。
1.2 后端注意事项
文件上传操作,后端需要注意:
(1)可以在项目的配置文件 application.properties或application.yml中设置文件大小限制,以避免上传过大的文件导致服务器资源耗尽,例如:
(2)后端需要写一个处理上传文件的处理器,把接收到的文件保存到服务器指定目录下等其他操作。
1.3 前后端完整示例程序
1.3.1 前端
html
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/html">
<head>
<meta charset="UTF-8">
<title>文件上传和下载</title>
</head>
<body>
<form action="/file/upload" method="post" enctype="multipart/form-data">
用户名:<input type="text" name="username"/><br/>
头 像 :<input type="file" name="headerImg" /><br/>
生活照:<input type="file" name="lifeImages" multiple></br>
<input type="submit" value="提交"/>
</form>
</body>
</html>
1.3.2 后端
html
package com.shg.springmvc.controller;
import org.springframework.stereotype.Controller;
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.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.nio.file.Paths;
@Controller
public class PageTestController {
@RequestMapping(value = "/file/upload", method = RequestMethod.POST)
@ResponseBody
public String fileUpload(@RequestParam(value = "headerImg") MultipartFile file,
@RequestParam(value = "lifeImages") MultipartFile[] lifeImages,
@RequestParam(value = "username") String userName) throws IOException {
System.out.println("用户名:" + userName);
System.out.println("头像 - 文件名称:" + file.getOriginalFilename());
file.transferTo(Paths.get("D:\\tempPic\\" + file.getOriginalFilename()));
for (MultipartFile lifeImage : lifeImages) {
System.out.println("生活照 - 文件名称:" + lifeImage.getOriginalFilename());
lifeImage.transferTo(Paths.get("D:\\tempPic\\" + file.getOriginalFilename()));
}
return "success";
}
}
2. 文件下载
文件下载的写法比较固定,代码如下:
java
package com.shg.springmvc.controller;
import org.springframework.core.io.InputStreamResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
@RestController
public class ResponseTestController {
/**
* 问题一:如果文件名称中包含中文,那么浏览器会乱码
* 问题二:如果下载的文件比较大,会oom(内存溢出)
*
* @return
* @throws IOException
*/
@RequestMapping(value = "/download", method = RequestMethod.GET)
public ResponseEntity<InputStreamResource> response_02() throws IOException {
// 获取要下载的文件流
String filePath = "D:\\tempPic\\生活照3.jpg";
File file = new File(filePath);
FileInputStream fileInputStream = new FileInputStream(file);
// 解决问题一:使用URLEncoder.encode()方法对文件名称进行编码
String fileName = URLEncoder.encode("你好啊.jpg", StandardCharsets.UTF_8);
// 解决问题二:为了避免一次性读取文件过大,导致内存溢出,可以使用 InputStreamResource 来读取文件(将文件流包装成Resource对象)
InputStreamResource inputStreamResource = new InputStreamResource(fileInputStream);
return ResponseEntity.ok()
// 设置响应头,告诉浏览器如何处理
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + fileName)
// 下载文件的大小
.contentLength(file.length())
// 内容类型:流
.contentType(MediaType.APPLICATION_OCTET_STREAM)
// 响应体
.body(inputStreamResource);
}
}