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

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

前言

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

文件多线程兼多文件上传

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);
    }


相关文章
|
6天前
|
前端开发 JavaScript Java
基于Java+Springboot+Vue开发的大学竞赛报名管理系统
基于Java+Springboot+Vue开发的大学竞赛报名管理系统(前后端分离),这是一项为大学生课程设计作业而开发的项目。该系统旨在帮助大学生学习并掌握Java编程技能,同时锻炼他们的项目设计与开发能力。通过学习基于Java的大学竞赛报名管理系统项目,大学生可以在实践中学习和提升自己的能力,为以后的职业发展打下坚实基础。
20 3
基于Java+Springboot+Vue开发的大学竞赛报名管理系统
|
7天前
|
前端开发 JavaScript Java
基于Java+Springboot+Vue开发的蛋糕商城管理系统
基于Java+Springboot+Vue开发的蛋糕商城管理系统(前后端分离),这是一项为大学生课程设计作业而开发的项目。该系统旨在帮助大学生学习并掌握Java编程技能,同时锻炼他们的项目设计与开发能力。通过学习基于Java的蛋糕商城管理系统项目,大学生可以在实践中学习和提升自己的能力,为以后的职业发展打下坚实基础。
20 3
基于Java+Springboot+Vue开发的蛋糕商城管理系统
|
7天前
|
前端开发 JavaScript Java
基于Java+Springboot+Vue开发的美容预约管理系统
基于Java+Springboot+Vue开发的美容预约管理系统(前后端分离),这是一项为大学生课程设计作业而开发的项目。该系统旨在帮助大学生学习并掌握Java编程技能,同时锻炼他们的项目设计与开发能力。通过学习基于Java的美容预约管理系统项目,大学生可以在实践中学习和提升自己的能力,为以后的职业发展打下坚实基础。
21 3
基于Java+Springboot+Vue开发的美容预约管理系统
|
2天前
|
Java API
Java的日期类都是怎么用的
【10月更文挑战第1天】本文介绍了 Java 中处理日期和时间的三个主要类:`java.util.Date`、`java.util.Calendar` 和 `java.time` 包下的新 API。`Date` 类用于表示精确到毫秒的瞬间,可通过时间戳创建或获取当前日期;`Calendar` 抽象类提供丰富的日期操作方法,如获取年月日及时区转换;`java.time` 包中的 `LocalDate`、`LocalTime`、`LocalDateTime` 和 `ZonedDateTime` 等类则提供了更为现代和灵活的日期时间处理方式,支持时区和复杂的时间计算。
26 14
|
5天前
|
JavaScript 前端开发 Java
SpringBoot项目的html页面使用axios进行get post请求
SpringBoot项目的html页面使用axios进行get post请求
18 6
|
6天前
|
消息中间件 Java Kafka
springboot项目启动报错-案例情景介绍
springboot项目启动报错-案例情景介绍
15 2
|
6天前
|
安全 Java 编译器
java访问类字段
java访问类字段
|
6天前
|
JSON NoSQL Java
redis的java客户端的使用(Jedis、SpringDataRedis、SpringBoot整合redis、redisTemplate序列化及stringRedisTemplate序列化)
这篇文章介绍了在Java中使用Redis客户端的几种方法,包括Jedis、SpringDataRedis和SpringBoot整合Redis的操作。文章详细解释了Jedis的基本使用步骤,Jedis连接池的创建和使用,以及在SpringBoot项目中如何配置和使用RedisTemplate和StringRedisTemplate。此外,还探讨了RedisTemplate序列化的两种实践方案,包括默认的JDK序列化和自定义的JSON序列化,以及StringRedisTemplate的使用,它要求键和值都必须是String类型。
redis的java客户端的使用(Jedis、SpringDataRedis、SpringBoot整合redis、redisTemplate序列化及stringRedisTemplate序列化)
|
2月前
|
Java 开发者
奇迹时刻!探索 Java 多线程的奇幻之旅:Thread 类和 Runnable 接口的惊人对决
【8月更文挑战第13天】Java的多线程特性能显著提升程序性能与响应性。本文通过示例代码详细解析了两种核心实现方式:Thread类与Runnable接口。Thread类适用于简单场景,直接定义线程行为;Runnable接口则更适合复杂的项目结构,尤其在需要继承其他类时,能保持代码的清晰与模块化。理解两者差异有助于开发者在实际应用中做出合理选择,构建高效稳定的多线程程序。
47 7
|
2月前
|
Oracle 安全 Java
JDK8到JDK28版本升级的新特性问题之在Java 15及以后的版本中,密封类和密封接口是怎么工作的
JDK8到JDK28版本升级的新特性问题之在Java 15及以后的版本中,密封类和密封接口是怎么工作的
下一篇
无影云桌面