【Java项目】SpringBoot实现一个请求同时上传多个文件和类并附上代码实例

文章目录

  • 前言
  • 文件多线程兼多文件上传
  • @RequestParam和@RequestPart的区别

前言

项目在做二手市场,然后商品的提交我们希望对商品的描述和商品的照片能一起传递到同一个接口来统一处理,而不是分发到两个接口中去处理,因为如果分到两个接口那么会特别麻烦。

文件多线程兼多文件上传

SpringBoot多线程兼多文件同时上传

@RequestParam和@RequestPart的区别

区别可以看这篇文章

在这里插入图片描述
可以先看上面这张图片展示出来的接口,我是用的是form-data表单提交,并且我并没有设定secHandGoods这个字段为application/json提交,那么默认他就是以字符串提交过去的,也就是说这里Java代码我只能使用@RequestParam的方式,如下
在这里插入图片描述
然后使用JSON.parseObject来完成对象类型的转换。
而如果我是用的是Postman进行请求提交,那么由于postman可以设定form-data提交的时候的content-type,那么我就可以使用@RequestPart来完成提交,如下
在这里插入图片描述
而postman这边设定secHandGoods这个参数为application/json即可
在这里插入图片描述
具体的需求对接其实是要看前端的,我们更倾向与使用第二种,因为如果使用JSON.parseObject,他的性能损耗还是有的。
大概的代码如下:
代码还没有优化,都是随便写写的,能大概跑完就行哈哈哈哈

/**
     * 用户更新自己的闲置商品
     *
     * @param sechandGoods
     * @return
     */
    @PutMapping("/updateGoods")
    public BaseResponse updateGoods(
            @RequestPart("files") MultipartFile[] files,
            //@RequestParam("secHandGoods") String jsonStr,
            @RequestPart("secHandGoods") SechandGoods sechandGoods,
            HttpServletRequest request) throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
        //SechandGoods sechandGoods = JSON.parseObject(jsonStr, SechandGoods.class);
        WXSessionModel user = (WXSessionModel) request.getSession().getAttribute("user");
        sechandGoods.setUserId(Long.valueOf(user.getUserId()));
        minioSysFileService.deleteFiles(sechandGoods.getGoodsPhotos());
        //MultipartFile[] files = sechandGoods.getFiles();
        CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<>();
        CountDownLatch countDownLatch = new CountDownLatch(files.length);
        for (int i = 0; i < files.length; i++) {
            try {
                MultipartFile file = files[i];
                //TODO 使用CountDownLaunch或者ComplatableFuture或者Semaphore
                //来完成多线程的文件上传
                fileThreadPool.submit(() -> {
                    try {
                        String url = minioSysFileService.uploadFile(file);
                        list.add(url);
                    } catch (Exception e) {
                        throw new RuntimeException(e);
                    } finally {
                        //表示一个文件已经被完成
                        countDownLatch.countDown();
                    }
                });
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
        try {
            //阻塞直到所有的文件完成复制
            countDownLatch.await();
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        //统计每个文件的url
        String photoUrls = String.join(",", list);
        sechandGoods.setGoodsPhotos(photoUrls);
        int isUpdate = sechandGoodsService.updateSechandGoods(sechandGoods);
        //if (isUpdate == 0) {
        //    return ResponseData.error(CodeEnum.BODY_NOT_MATCH);
        //}
        return ResponseData.success(sechandGoods);
    }

    @Autowired
    private MinioSysFileServiceImpl minioSysFileService;
    @Autowired
    @Qualifier("fileThreadPool")
    private ThreadPoolExecutor fileThreadPool;

    /**
     * 用户上传商品
     *
     * @param sechandGoods
     * @param request
     * @return
     */
    @PostMapping("/saveGoods")
    public BaseResponse saveGoodByUserId(
            @RequestPart("files") MultipartFile[] files,
            //@RequestParam("secHandGoods") String jsonStr,
            @RequestPart("secHandGoods") SechandGoods sechandGoods,
            HttpServletRequest request) {
        WXSessionModel user = (WXSessionModel) request.getSession().getAttribute("user");
        //SechandGoods sechandGoods = JSON.parseObject(jsonStr, SechandGoods.class);
        sechandGoods.setUserId(Long.valueOf(user.getUserId()));
        //MultipartFile[] files = sechandGoods.getFiles();
        CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<>();
        CountDownLatch countDownLatch = new CountDownLatch(files.length);
        for (int i = 0; i < files.length; i++) {
            try {
                MultipartFile file = files[i];
                //TODO 使用CountDownLaunch或者ComplatableFuture或者Semaphore
                //来完成多线程的文件上传
                fileThreadPool.submit(() -> {
                    try {
                        String url = minioSysFileService.uploadFile(file);
                        list.add(url);
                    } catch (Exception e) {
                        throw new RuntimeException(e);
                    } finally {
                        //表示一个文件已经被完成
                        countDownLatch.countDown();
                    }
                });
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
        try {
            //阻塞直到所有的文件完成复制
            countDownLatch.await();
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        //统计每个文件的url
        String photoUrls = String.join(",", list);
        sechandGoods.setGoodsPhotos(photoUrls);
        sechandGoodsService.insertSechandGoods(sechandGoods);
        return ResponseData.success(sechandGoods);
    }

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

大语言模型带来的一些启发

仅代表个人看法&#xff0c;不喜勿喷。 The limits of my language means the limits of my world. (Ludwig Wittgenstein) 我的语言的极限意味着我的世界的极限。——维特根斯坦 大语言模型解决的不仅是处理文本相关问题&#xff0c;它带来的是人对世界的理解&#xff0c;或者…

华为网络篇 单臂路由-17

实验难度 2实验复杂度2目录 一、实验原理 二、实验拓扑 三、实验步骤 四、实验过程 总结 一、实验原理 单臂路由&#xff08;router-on-a-stick&#xff09;是指在路由器的一个接口上通过配置子接口&#xff08;或“逻辑接口”&#xff0c;并不存在真正物理接口&…

EasyExcel的简单使用(easyExcel和poi)

EasyExcel的简单使用 前言 Excel读 1.实体类 2.读监听器与测试类 3.输出结果 Excel写 1.实体类 2.写入Excel的测试类 3.输出结果 填充Excel 1.Excel模板 2.测试类 3.输出结果 前言 EasyExcel类是一套基于Java的开源Excel解析工具类&#xff0c;相较于传统的框架如Apache poi、…

Go 语言数组和切片的区别

原文链接&#xff1a; Go 语言数组和切片的区别 在 Go 语言中&#xff0c;数组和切片看起来很像&#xff0c;但其实它们又有很多的不同之处&#xff0c;这篇文章就来说说它们到底有哪些不同。 另外&#xff0c;这个问题在面试中也经常会被问到&#xff0c;属于入门级题目&…

堆及其堆排序

堆是一种特殊的数据结构&#xff0c;底层实现是靠数组存储以及完全二叉树的性质 文章目录一、堆概念二、堆实现三、堆源码四、堆排序一、堆概念 完全二叉树用数组来存储可以达到空间的有效利用且可以直观反映它们之间的逻辑关系&#xff0c;双亲与孩子之间的关系。一般在数组中…

一文说透虚拟内存

为什么我们需要虚拟内存 提供一个虚拟化封装&#xff0c;让上层的程序员不用担心内存分配&#xff0c;物理地址的总大小。同时如果要手动管理内存是一件麻烦的事&#xff0c;比如一个程序读到另一个程序的物理地址&#xff0c;并且也很难保障多个处理器不会同时读取写入同一块…

GitHub Action 使用

GitHub Action 使用 GitHub Actions 是一种持续集成和持续交付 (CI/CD) 平台&#xff0c;可用于自动执行生成、测试和部署管道。 您可以创建工作流程来构建和测试存储库的每个拉取请求&#xff0c;或将合并的拉取请求部署到生产环境。GitHub 提供 Linux、Windows 和 macOS 虚拟…

训练AI数据模型所需要的高性能计算机配置

目录 配置一 配置二 配置三 云服务器和超级计算机 AI模型训练是一种机器学习的过程&#xff0c;通过训练深度学习模型来自动化处理数据和完成任务。AI训练可以帮助企业和研究人员开发出更加智能、高效的应用&#xff0c;从而提高生产力和创新能力。 以下是按训练性能从低到…

对挖矿病毒 kdevtmpfsi 的处理办法

需求背景&#xff1a; 服务器CPU资源使用一直处于100%的状态&#xff0c;通过 top 命令查看&#xff0c;发现可疑进程 kdevtmpfsi。通过 google搜索&#xff0c;发现这是挖矿病毒。 排查方法 首先&#xff1a;查看 kdevtmpfsi 进程&#xff0c;使用 ps -ef | grep kdevtmpfsi …

数据结构之线性表

文章目录1. 线性表的定义2. 线性表的抽象数据类型3. 线性表的顺序存储结构4. 线性表的链式存储结构5. 单链表结构和顺序存储结构优缺点6. 静态链表7. 循环链表8. 双向链表1. 线性表的定义 零个或多个数据元素的有限序列 线性表的定义中强调有限和序列两个方面。 有限&#xff…

华硕ROG|玩家国度 冰刃7双屏 GX650PY Windows11原厂预装系统 工厂模式恢复安装带ASUSRecevory一键还原

华硕ROG|玩家国度 冰刃7双屏 GX650PY Windows11原厂预装系统 工厂模式恢复安装带ASUSRecevory一键还原 文件地址&#xff1a;https://pan.baidu.com/s/1snKOsH3OMl3GZLqeAf-GLA?pwd8888 华硕工厂恢复系统 &#xff0c;安装结束后带隐藏分区以及机器所有驱动软件 需准备一个…

【树】你真的会二叉树了嘛? --二叉树LeetCode专题Ⅲ

Halo&#xff0c;这里是Ppeua。平时主要更新C语言&#xff0c;C&#xff0c;数据结构算法......感兴趣就关注我吧&#xff01;你定不会失望。 &#x1f308;个人主页&#xff1a;主页链接 &#x1f308;算法专栏&#xff1a;专栏链接 我会一直往里填充内容哒&#xff01; &…

MySQL基础-变量/流程控制/游标/触发器

文章目录MySQL基础-变量/流程控制/游标/触发器一、变量1、系统变量2、用户变量二、流程控制1、分支语句2、循环语句3、跳转语句三、游标1、概念2、使用四、触发器1、触发器概念2、触发器使用3、触发器的优缺点MySQL基础-变量/流程控制/游标/触发器 一、变量 在MySQL数据库的存…

RocketMQ水平扩展及负载均衡详解

文章目录 Broker端水平扩展Broker负载均衡commit logProducer负载均衡Consumer负载均衡集群模式广播模式RocketMQ是一个分布式具有高度可扩展性的消息中间件。本文旨在探索在broker端,生产端,以及消费端是如何做到横向扩展以及负载均衡的。 Broker端水平扩展 Broker负载均衡…

前端项目-05-轮播图banner和Floor组件开发-全局轮播图组件抽取

目录 1-轮播图模块数据开发 2-floor组件开发 3-抽取全局轮播图组件 1-轮播图模块数据开发 轮播图需要用到swiper插件&#xff0c;先安装5.4.5版本的swiper&#xff1a;npm install --save swiper^5.4.5 --force 模拟从服务器获取数据&#xff1b; 1-编写mockRequests的js…

【ACWing算法课】二分查找

前言&#x1f349; 二分查找一个简单的算法&#xff0c;但是因为边界问题往往写不好。特此记录模板&#xff0c;以便快捷使用。 [二分查找]从列表q找到第一个>k的数&#xff0c;返回位置&#x1f451; [二分查找]从列表q找到第一个>k的数&#xff0c;返回位置def bsear…

three.js实现3d球体树状结构布局——树状结构的实现

目录系列文章安装依赖基本分析实体类场景相机渲染器辅助线环境光点光源球形几何体球形几何体的材质线几何体线几何体的材质物体文本轨道控制实现效果实现源码参考文档系列文章 three.js实现3d球体树状结构布局——添加入场、出场、点击放大等动画 安装依赖 npm i three three…

Adaptive AUTOSAR——Time Synchronization(VRTE 3.0 R21-11)

15 Time Synchronization 15.1 What is Time Synchronization? 时间同步是自适应平台基础中的一个功能集群。时间同步通过库向应用程序提供C API&#xff0c;该库作为RTA-VRTE入门套件的一部分提供&#xff0c;并与应用程序链接以访问该功能。 本版本包含非常少量的时间同步…

ASIC-WORLD Verilog(1)一日Verilog

写在前面 在自己准备写一些简单的verilog教程之前&#xff0c;参考了许多资料----asic-world网站的这套verilog教程即是其一。这套教程写得极好&#xff0c;奈何没有中文&#xff0c;在下只好斗胆翻译过来&#xff08;加了自己的理解&#xff09;分享给大家。 这是网站原文&…

Helm学习笔记

文章目录概念定义helm组件helm的工作流程helm安装helm仓库helm部署应用helm应用的更新或回退或卸载概念 定义 学习helm首先得了解helm是什么&#xff0c;我们先来看一下helm的定义&#xff1a;helm是将kubernetes的各种资源对象打包&#xff0c;类似于Linux中的yum工具&#…
最新文章