# 第十六章:文件上传和下载
## 1.文件上传
### 1.创建项目,导包
```java
org.springframework
spring-web
4.3.6.RELEASE
org.springframework
spring-webmvc
4.3.6.RELEASE
commons-io
commons-io
2.5
commons-fileupload
commons-fileupload
1.3.2
javax.servlet
servlet-api
2.5
```
### 2.web.xml
```java
springmvc
org.springframework.web.servlet.DispatcherServlet
contextConfigLocation
classpath:springmvc-config.xml
1
springmvc
/
```
### 3.springmvc-config.xml
```java
```
### 4.创建fileUpload.jsp
webapp下的jsp文件可以通过url直接访问
而WEB-INF下的js文件需要控制器中的方法返回才可以访问到
```html
Title
```
### 5.创建success.jsp error.jsp
```html
上传失败
```
```html
上传成功
```
![image-20220517103654553](https://lsky.hhdxw.top/imghub/img/image-20220517103654553.png)
### 6.创建控制器
```java
package com.gzh.controller;
/**
* 文件上传
*/
@Controller
public class FileUploadController {
/**
* 执行文件上传
*/
@RequestMapping("/fileUpload")
public String handleFormUpload(@RequestParam("name") String name,
@RequestParam("uploadfile") List uploadfile,
HttpServletRequest request) {
// 判断所上传文件是否存在
if (!uploadfile.isEmpty() && uploadfile.size() > 0) {
//循环输出上传的文件
for (MultipartFile file : uploadfile) {
// 获取上传文件的原始名称
String originalFilename = file.getOriginalFilename();
// 设置上传文件的保存地址目录
String dirPath =
request.getSession().getServletContext().getRealPath("/upload/");
File filePath = new File(dirPath);
// 如果保存文件的地址不存在,就先创建目录
if (!filePath.exists()) {
filePath.mkdirs();
}
// 使用UUID重新命名上传的文件名称(上传人_uuid_原始文件名称)
String newFilename = name + "_" + UUID.randomUUID() +
"_" + originalFilename;
try {
// 使用MultipartFile接口的方法完成文件上传到指定位置
file.transferTo(new File(dirPath + newFilename));
} catch (Exception e) {
e.printStackTrace();
return "error";
}
}
// 跳转到成功页面
return "success";
} else {
return "error";
}
}
}
```
### 7.发布项目
![image-20220517105222969](https://lsky.hhdxw.top/imghub/img/image-20220517105222969.png)
![image-20220517105211357](https://lsky.hhdxw.top/imghub/img/image-20220517105211357.png)
![image-20220517105334825](https://lsky.hhdxw.top/imghub/img/image-20220517105334825.png)
## 2.文件下载
### 1.创建download.jsp
```html
下载页面
文件下载
">
中文名称文件下载
```
### 2.添加控制器
下载文件的名字会产生乱码
```java
@RequestMapping("/download")
public ResponseEntity fileDownload(HttpServletRequest request,String filename) throws Exception {
// 指定要下载的文件所在路径
String path = request.getSession().getServletContext().getRealPath("/upload/");
// 创建该文件对象
File file = new File(path + File.separator + filename);
// 设置响应头
HttpHeaders headers = new HttpHeaders();
// 通知浏览器以下载的方式打开文件
headers.setContentDispositionFormData("attachment", filename);
// 定义以流的形式下载返回文件数据
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
// 使用Sring MVC框架的ResponseEntity对象封装返回下载数据
return new ResponseEntity(FileUtils.readFileToByteArray(file),
headers, HttpStatus.OK);
}
```
能保证下载的文件中文名字
```java
@RequestMapping("/download")
public ResponseEntity fileDownload(HttpServletRequest request,String filename) throws Exception {
// 指定要下载的文件所在路径
String path = request.getSession().getServletContext().getRealPath("/upload/");
// 创建该文件对象
File file = new File(path + File.separator + filename);
// 对文件名编码,防止中文文件乱码
filename = this.getFilename(request, filename);
// 设置响应头
HttpHeaders headers = new HttpHeaders();
// 通知浏览器以下载的方式打开文件
headers.setContentDispositionFormData("attachment", filename);
// 定义以流的形式下载返回文件数据
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
// 使用Sring MVC框架的ResponseEntity对象封装返回下载数据
return new ResponseEntity(FileUtils.readFileToByteArray(file),
headers, HttpStatus.OK);
}
/**
* 根据浏览器的不同进行编码设置,返回编码后的文件名
*/
public String getFilename(HttpServletRequest request,String filename) throws Exception {
// IE不同版本User-Agent中出现的关键词
String[] IEBrowserKeyWords = {"MSIE", "Trident", "Edge"};
// 获取请求头代理信息
String userAgent = request.getHeader("User-Agent");
for (String keyWord : IEBrowserKeyWords) {
if (userAgent.contains(keyWord)) {
//IE内核浏览器,统一为UTF-8编码显示
return URLEncoder.encode(filename, "UTF-8");
}
}
//火狐等其它浏览器统一为ISO-8859-1编码显示
return new String(filename.getBytes("UTF-8"), "ISO-8859-1");
}
```
### 3.发布项目
用第一个控制器,下载的文件不是中文名称
![image-20220517112749837](https://lsky.hhdxw.top/imghub/img/image-20220517112749837.png)
用第二个控制器,下载的文件是中文名称
![image-20220517113013424](https://lsky.hhdxw.top/imghub/img/image-20220517113013424.png)