1、上传附件
文件上传时,对页面的form表单要求如下:
- 1、method=“post” 采用post方式提交数据
- 2、enctype=“mutlipart/form-data” 采用mutlipart 格式上传文件
- 3、type=“file” 采用input的file控件上传
服务器接受客户端页面上传的文件,通常都会使用Apache的两个组件
- 1、commons-fileupload
- 2、commons-io
Spring框架在spring-web包中对文件上传进行了封装,大大简化了服务端代码,我们只需要在Controller的方法中声明一个MultipartFile类型的参数,即可接收上传的文件,见如下代码
package com.itheima.reggie.controller;
import com.itheima.reggie.common.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
import java.util.UUID;
@RestController
@Slf4j
@RequestMapping("/common")
public class CommonController {
@Value("${reggie.upload.img.path}")
private String basePath;
@PostMapping("/upload")
public R<String> upload(MultipartFile file) {
try {
// 文件会被临时存储在本地的某个地方,如果不转存,线程结束后,临时文件也会被清除
log.info(file.toString());
/**
* 将文件转存
* 1、获取原始文件名
* 2、通过 substring 方法获取原文件名的后缀
* 3、随机生成一个uuid,拼接文件名后缀得到一个新的唯一文件名
* 4、检查目录是否存在,不存在则创建
* 5、转存
* */
String originalFilename = file.getOriginalFilename();
String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));
String fileName = UUID.randomUUID() + suffix;
File dir = new File(basePath);
if (!dir.exists()){
// 目录不存在创建文件夹
dir.mkdir();
}
file.transferTo(new File(basePath + fileName));
return R.success(fileName);
} catch (IOException e) {
e.printStackTrace();
return R.error("上传失败!");
}
}
}
application.yml 文件中增加配置 reggie
server:
port: 9080
spring:
application:
name: reggie_take_out
datasource:
druid:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/reggie?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&useSSL=false&allowPublicKeyRetrieval=true
username: root
password: admin
type: com.alibaba.druid.pool.DruidDataSource
mybatis-plus:
configuration:
#在映射实体或者属性时,将数据库中表名和字段名中的下划线去掉,按照驼峰命名法映射 实体类属性名:idNumber -> 数据库字段名:id_number
map-underscore-to-camel-case: true
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
global-config:
db-config:
id-type: AUTO
reggie:
upload:
img:
path: /Users/abc/Documents/picDir/
2、附件下载
通常浏览器进行文件下载,有两种表现形式
- 1、以附件形式下载,弹出保存对话框,将文件保存到指定目录
- 2、直接在浏览器中打开(以照片在页面展示为例)
/**
* 1、文件下载(在页面中展示)
* @param name 文件名
* @param response
*/
@GetMapping("/download")
public void download(String name, HttpServletResponse response) {
try {
// 输入流。通过输入流读取文件内容
FileInputStream fileInputStream = new FileInputStream(new File(basePath + name));
// 输出流,通过输出流将文件写会浏览器,在浏览器中展示图片
ServletOutputStream outputStream = response.getOutputStream();
response.setContentType("image/jpeg");
int len = 0;
byte[] bytes = new byte[1024];
while ((len = fileInputStream.read(bytes)) != -1){
outputStream.write(bytes, 0, len);
outputStream.flush();
}
// 释放资源
fileInputStream.close();
outputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}