文件上传和下载(Web)
文件上传
概述
文件上传,也称为upload, 是指将本地图片、视频、音频等文件上传到服务器上,可以供其他用户浏览或下载的过程。文件上传在项目中应用非常广泛,我们经常发微博、发微信朋友圈都用到了文件上传功能。文件上传时,对页面的 form 表单有如下要求:
要求 | 含义 |
---|---|
method="post" | 采用post 方式提交数据 |
enctype="multipart/form-data" | 采用multipart 格式上传文件 |
type="file" | 使用input 的file 控件上传 |
举例:
<form method="post"action="/common/upload"enctype="multipart/form-data">
<input name="myFile"type="file"/
<input type="submit"value=" 提交 "/>
</form>
目前一些前端组件库也提供了相应的上传组件,但是底层原理还是基于 fom 表单的文件上传。
服务端实现文件上传
服务端要接收客户端页面上传的文件,通常都会使用 Apache 的两个组件:
-
commons-fileupload
-
commons-io
Spring 框架在 spring-web 包中对文件上传进行了封装,大大简化了服务端代码,我们只需要在 Controller 的方法中声明一个 MultipartFile 类型的参数即可接收上传的文件,例如:
@PostMapping("/upload")
public void upload(MultipartFile file){
// 形参名称要和 form 表单的 name 保持一致!!
log.info(file.toString());
// 处理文件的具体逻辑 ...
}
❗注:
- file 是一个临时文件,保存了关于文件的相关属性。需要转存到指定位置,否则本次请求完成后临时文件会删除。
MultipartFile
类型的参数要和前端form
表单的 **name
属性的值 ** 一致,若不一致,则该参数内容为 null。
文件下载
概述
文件下载,也称为download
, 是指将文件从服务器传输到本地计算机的过程。通过浏览器进行文件下载,通常有两种表现形式:
- 以附件形式下载,弹出保存对话框,将文件保存到指定 ** 磁盘 ** 目录
- 直接在 ** 浏览器 ** 中打开
通过浏览器进行文件下载,本质上就是服务端将文件以流 的形式写回浏览器的过程。(服务端 → 浏览器)
案例:
需求 将图片上传到服务器,将文件传输到本地计算机的浏览器上并打卡。
实现:
step1: 文件上传,为保证上传图片 名称唯一性,需要重命名图片,为了保证图片 类型一致,需要获取图片后缀名。图片名后期要存入数据库,在文件下载时要通过图片名作为唯一标识来获取图片,所以需要将图片名返回给前端,以便前端通过 url + 图片名来获取到响应的图片。代码示例:
@PostMapping("upload")
public Result<String> upload(MultipartFile file) {
//file 为临时文件,需要将 file 放到指定位置
// 原始文件名
String originalFilename = file.getOriginalFilename();
//. 后缀名
String suffix = originalFilename.substring(originalFilename.lastIndexOf(".") );
//uuid 创建文件名,保证文件名唯一
String fileName = UUID.randomUUID().toString() + suffix;
try {
file.transferTo(new File(basePath + fileName));
} catch (Exception e) {
e.printStackTrace();
}
return Result.success(fileName);
}
step2: 文件下载,通过输入流获取图片,通过输出流将图片显示到浏览器。通过后续操作数据库的操作可以将图片名保存到数据库中。
/**
* 文件下载
* 没有返回值,通过将数据写回页面即可。通过输出流将图片显示到前端页面
*/
@GetMapping("/download")
public void download(String name, HttpServletResponse response){
log.info(" 文件下载,文件名:{}", name);
try (
// 输入流获取文件
InputStream is = new FileInputStream(new File(basePath + name));
// 通过输出流将文件显示到浏览器上
OutputStream os = response.getOutputStream();
) {
//
response.setContentType("images/jpeg");
int len = 0;
byte[] bytes = new byte[1024];
while ((len = is.read(bytes)) != -1) {
os.write(bytes, 0, len);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
❗注:
- 图片下载要加上 response.setContentType("images/jpeg");