Spring Cloud微服务项目文件上传/下载

news2024/9/22 1:10:06

        在现代的微服务架构中,文件上传与下载是常见的需求,尤其是在需要处理大量文件数据的系统中。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接口测试工具上调试的结果:

点击 下载 按钮后,文件将会被保存到自己的电脑上 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1995182.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Kubernetes】k8s集群之Pod容器资源限制和三种探针

目录 一、Pod容器的资源限制 1.资源限制 2.Pod 和容器的资源请求与限制 3.CPU 资源单位 4.内存资源单位 二、Pod容器的三种探针 1.探针的三种规则 2.Probe支持三种检查方法&#xff1a; 一、Pod容器的资源限制 1.资源限制 当定义 Pod 时可以选择性地为每个容器设定所…

成都数字产业中心崛起,树莓集团如何加速国际数字影像产业园的全球步伐?

在数字化浪潮的推动下&#xff0c;成都数字产业中心近年来强势崛起&#xff0c;展现出令人瞩目的发展态势。据统计&#xff0c;过去五年间&#xff0c;成都数字产业的年均增长率超过了 20%&#xff0c;这一数据充分证明了其强大的发展动力。而在这片充满活力与创新的土地上&…

数据结构 JAVADS ——部分栈题目分享 (持续更新版)

前言 大概十天前,笔者更新了如何手搓一个简易的栈 入门数据结构JAVA DS ——手搓 栈-CSDN博客 在本篇博客中,笔者就分享几个题目,这同样是一个持续 更新的博客,但是我不保证更新频率就是了 哈哈! 那么我们就来看题目吧 第一题 1.小蓝的括号串1 - 蓝桥云课 (lanqiao.cn) …

如何在 Windows 上设置 MacOS 云主机

在Windows上设置MacOS云主机实际上涉及在Windows环境中模拟或远程管理MacOS系统&#xff0c;因为直接在Windows上运行MacOS作为云主机的主操作系统是不可能的&#xff0c;因为MacOS是为苹果硬件设计的。不过&#xff0c;有几种方法可以实现类似的功能&#xff1a; 1. 使用虚拟机…

Haskell HTTP请求:如何解读响应状态

在互联网技术领域&#xff0c;HTTP请求是客户端与服务器之间通信的基础。无论是网页浏览、API调用还是网络服务的交互&#xff0c;HTTP协议都扮演着核心角色。在本文中&#xff0c;我们将探讨如何在Haskell编程语言中发起HTTP请求&#xff0c;并重点介绍如何解读HTTP响应状态。…

学懂C++ (二十一):高级教程——深入C++多线程开发详解

C多线程开发详解 多线程编程是现代应用程序开发中不可或缺的一部分。C11引入了对多线程的支持&#xff0c;使得程序员能够更方便地利用多核处理器&#xff0c;提高程序的性能和响应能力。本文将全面而深入地探讨C的多线程相关概念&#xff0c;包括线程的创建与管理、互斥量…

PDF怎么在线转Word?介绍四种转换方案

PDF怎么在线转Word&#xff1f;在数字化办公时代&#xff0c;文档的互换性变得尤为重要。PDF格式因其跨平台兼容性和版面固定性而广受欢迎&#xff0c;但有时我们可能需要将PDF文件转换为Word文档&#xff0c;以便进行编辑或进一步处理。以下是四种常见的在线PDF转Word的方法&a…

大数据湖体系规划与建设方案(51页PPT)

方案介绍&#xff1a; 大数据湖通过集中存储各种类型的数据&#xff08;包括结构化、半结构化和非结构化数据&#xff09;&#xff0c;提供了更加灵活、可扩展的数据处理和分析能力。其核心理念是“存储一切&#xff0c;分析一切&#xff0c;创建所需”&#xff0c;即将所有数…

【论文复现】Transformer

Transformer 前言网络架构数据处理词嵌入向量位置编码 模型定义多头注意力机制编码器Encoder解码器Decoder 前言 Transformer应用范围非常广泛&#xff0c;涵盖了自然语言处理、时间序列数据预测、图像处理等领域。由于笔者之前都是应用&#xff0c;但是对于原理并没有深刻理解…

树莓派Pico 2,RP2350 现已发售!

https://www.bilibili.com/video/BV1n5YeeMETu/?vd_sourcea637ced2b66f15709d16fcbaceeb47a9 我们很高兴地宣布推出Raspberry Pi Pico 2&#xff0c;我们的第二代微控制器板&#xff1a;采用了由我们自主设计的新款高性能安全型微控制器 RP2350。 Raspberry Pi Pico 2&#…

5 种经过验证的查询翻译技术可提高您的 RAG 性能

如何在用户输入模糊的情况下获得近乎完美的 LLM 性能 欢迎来到雲闪世界。你认为用户会向 LLM 提出完美的问题&#xff0c;这是大错特错。如果我们不直接执行&#xff0c;而是细化用户的问题&#xff0c;结果会怎样&#xff1f;这就是查询转换。 我们开发了一款应用程序&#x…

查看DrawCall流程 Unity工具 Frame Debug

切换帧率 基础面板 可以看到 我们可以通过切换面板 看DrwaCall产生 MainTex 就是材质了 如何优化&#xff1f; 合批 就会一次性直接渲染

双端队列Deque

Deque&#xff08;双端队列&#xff09;是一种允许在两端都进行插入和删除操作的线性数据结构。它在 Java Collections Framework 中作为一个重要的接口&#xff0c;具有以下结构特点&#xff1a; 1. 双端操作 两端插入和删除&#xff1a;与传统队列&#xff08;只能在一端入…

迭代次数顺序的双重性

(A,B)---6*30*2---(0,1)(1,0) 收敛误差为7e-4&#xff0c;收敛199次取迭代次数平均值&#xff0c; 让A是4a1&#xff0c;4a2&#xff0c;…&#xff0c;4a16&#xff0c;B全是0得到迭代次数的顺序就是1&#xff0c;2&#xff0c;…&#xff0c;16. 但是如果让训练集A-B矩阵的高…

kafka-go使用:以及kafka一些基本概念说明

关于kafka 作为开发人员kafka中最常关注的几个概念&#xff0c;是topic,partition和group这几个概念。topic是主题的意思&#xff0c;简单的说topic是数据主题&#xff0c;这样解释好像显得很苍白&#xff0c;只是做了个翻译。一图胜前言&#xff0c;我们还是通过图解来说明。…

PDF密码移除技巧: 五大 PDF 密码移除器

如果您想解密或删除 PDF 密码&#xff0c;该怎么办&#xff1f;PDF 是一种经常用于商业的格式&#xff0c;您可以在培训、教育和商业场合使用它。添加这些 PDF 文件的密码可以保护您的安全和隐私。因此&#xff0c;有很多 PDF 都用密码加密&#xff0c;当您想要查看这些 PDF 时…

PTrade常见问题系列22

反馈定义的上午7点执行run_daily函数&#xff0c;但是每周一上午都没法正常执行&#xff1f; 1、run_daily函数加载在initialize函数中&#xff0c;执行后才会创建定时任务&#xff1b; 2、由于周末会有例行重启操作&#xff0c;在重启以后拉起交易时相当于非交易日启动的交易…

【人工智能训练师】2 集群搭建

题目一、基础配置 core-site.xml参数配置详情 官方文档&#xff1a;http://hadoop.apache.org/docs/current/hadoop-project-dist/hadoop-common/core-default.xml core-default.xml与core-site.xml的功能是一样的&#xff0c;如果在core-site.xml里没有配置的属性&#xff0c…

【C++二分查找 决策包容性】1300. 转变数组后最接近目标值的数组和

本文涉及的基础知识点 C二分查找 决策包容性 LeetCode1300. 转变数组后最接近目标值的数组和 给你一个整数数组 arr 和一个目标值 target &#xff0c;请你返回一个整数 value &#xff0c;使得将数组中所有大于 value 的值变成 value 后&#xff0c;数组的和最接近 target …

【开端】JAVA中的切面使用

一、绪论 在不使用过滤器和 拦截器的前提下&#xff0c;如果统一对JAVA的 方法进行 管理。比如对一类方法或者类进行日志监控&#xff0c;前后逻辑处理。这时就可以使用到切面。它的本质还是一个拦截器。只是通过注解的方式来标识所切的方法。 二、JAVA中切面的使用实例 Aspec…