在现代的微服务架构中,文件上传与下载是常见的需求,尤其是在需要处理大量文件数据的系统中。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: 10MBmax-request-size: 10MB
3.编写Service和Controller层
3.1.创建文件上传方法
博主这里将MyBati 跟 MyBatis-Plus 二者结合一起使用,详情请参考:Spring Cloud微服务项目集成MyBatis
java">@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文档
java">@RestController
@RequestMapping("/api/auth/order")
@Tag(name = "订单管理")
public class OrderController {private final OrderService orderService;@Autowiredpublic 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.创建文件下载方法
java">@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.创建文件下载接口
java">@RestController
@RequestMapping("/api/auth/order")
@Tag(name = "订单管理")
public class OrderController {private final OrderService orderService;@Autowiredpublic 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接口测试工具上调试的结果:
点击 下载 按钮后,文件将会被保存到自己的电脑上