在现代的微服务架构中,文件上传与下载是常见的需求,尤其是在需要处理大量文件数据的系统中。Spring Cloud 提供了灵活的工具和组件,使得在微服务中实现文件上传和下载变得高效而简便。
本文博主将详细介绍如何在 Spring Cloud 微服务项目中实现文件上传和下载功能。
前置条件
在开始本文前,博主希望你已经初步创建了一个Spring Cloud微服务项目:Spring Cloud微服务项目创建请参考:Spring Cloud微服务项目搭建
1.添加依赖
在子模块的 pom.xml 中添加必要的依赖(博主这里是 order 模块):
<!-- oder 模块 pom.xml 配置文件 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
2.配置上传文件的大小限制
在 application.properties
或 application.yml
中配置文件上传的大小限制:
# application.properties 配置文件
spring.servlet.multipart.max-file-size=10MB
spring.servlet.multipart.max-request-size=10MB
或
# application.yml 配置文件
spring:
servlet:
multipart:
max-file-size: 10MB
max-request-size: 10MB
3.编写Service和Controller层
3.1.创建文件上传方法
博主这里将MyBati 跟 MyBatis-Plus 二者结合一起使用,详情请参考:Spring Cloud微服务项目集成MyBatis
@Service
public class OrderService extends ServiceImpl<OrderMapper, OrderInfoModel> {
/**
* 文件上传
*/
public String uploadFile(MultipartFile file) {
if (file.isEmpty()) {
return "上传文件不能为空!";
} else {
try {
// 创建目录
String uploadDir = "files/";
File dir = new File(uploadDir);
if (!dir.exists()) {
boolean created = dir.mkdirs();
if (!created) {
return "Failed to create upload directory.";
}
}
// 获取文件名
String fileName = file.getOriginalFilename();
Path path = Paths.get(uploadDir + fileName);
// 将文件保存到目标路径
Files.write(path, file.getBytes());
// 返回 文件存储路径
return "http://localhost:8000/api/auth/files/" + fileName;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
3.2.编写文件上传接口
这里Swagger接口文档请参考:Spring Cloud微服务项目聚合Swagger文档
@RestController
@RequestMapping("/api/auth/order")
@Tag(name = "订单管理")
public class OrderController {
private final OrderService orderService;
@Autowired
public OrderController(OrderService orderService) {
this.orderService = orderService;
}
@PostMapping("/uploadFile")
@Operation(summary = "文件上传", parameters = {
@Parameter(
name = "Authorization",
description = "TOKEN",
in = ParameterIn.HEADER,
required = true,
schema = @Schema(type = "string")
)
})
public String uploadFile(@RequestParam("file") MultipartFile file) {
return orderService.uploadFile(file);
}
}
3.3.创建文件下载方法
@Service
public class OrderService extends ServiceImpl<OrderMapper, OrderInfoModel> {
/**
* 文件上传
*/
public String uploadFile(MultipartFile file) {
if (file.isEmpty()) {
return "上传文件不能为空!";
} else {
try {
// 创建目录
String uploadDir = "files/";
File dir = new File(uploadDir);
if (!dir.exists()) {
boolean created = dir.mkdirs();
if (!created) {
return "Failed to create upload directory.";
}
}
// 获取文件名
String fileName = file.getOriginalFilename();
Path path = Paths.get(uploadDir + fileName);
// 将文件保存到目标路径
Files.write(path, file.getBytes());
// 返回 文件存储路径
return "http://localhost:8000/api/auth/files/" + fileName;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
/**
* 文件下载
*/
public ResponseEntity<Resource> downloadFile(String fileName) {
try {
// 构建文件路径
Path filePath = fileStorageLocation.resolve(fileName).normalize();
Resource resource = new UrlResource(filePath.toUri());
// 检查文件是否存在
if (!resource.exists()) {
return ResponseEntity.notFound().build();
}
// 设置响应头,触发下载
String contentType = "application/octet-stream"; // 默认的 MIME 类型
return ResponseEntity.ok()
.contentType(org.springframework.http.MediaType.parseMediaType(contentType))
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + resource.getFilename() + "\"")
.body(resource);
} catch (Exception e) {
return ResponseEntity.status(500).build();
}
}
3.4.创建文件下载接口
@RestController
@RequestMapping("/api/auth/order")
@Tag(name = "订单管理")
public class OrderController {
private final OrderService orderService;
@Autowired
public OrderController(OrderService orderService) {
this.orderService = orderService;
}
@PostMapping("/uploadFile")
@Operation(summary = "文件上传", parameters = {
@Parameter(
name = "Authorization",
description = "TOKEN",
in = ParameterIn.HEADER,
required = true,
schema = @Schema(type = "string")
)
})
public String uploadFile(@RequestParam("file") MultipartFile file) {
return orderService.uploadFile(file);
}
@GetMapping("/download/{fileName:.+}")
@Operation(summary = "文件下载", parameters = {
@Parameter(
name = "Authorization",
description = "TOKEN",
in = ParameterIn.HEADER,
required = true,
schema = @Schema(type = "string")
)
})
public ResponseEntity<Resource> downloadFile(@PathVariable String fileName) {
return orderService.downloadFile(fileName);
}
}
4.测试
4.1.文件上传测试
如果使用了Swagger 接口文档,那么直接在浏览器地址栏键入:
http://localhost:8000/doc.html
找到order服务中的文件上传接口,点击 选择文件 ==> 发送:
如果不出意外,你将会看到上面这个结构,我们拿到了后端返回的文件存储地址
4.2.文件下载测试
找到文件下载接口,点击 调试 ==> 输入我们要下载的文件名 ==> 点击发送:
当我们能够拿到这样的图片的时候,表示接口已经接通了,不过这里Swagger似乎没有提供下载的按钮,下面是博主在ApiFox接口测试工具上调试的结果:
点击 下载 按钮后,文件将会被保存到自己的电脑上