SpringCloudGateway网关服务实现文件上传功能

简介: SpringCloudGateway网关服务实现文件上传功能

image.png

@[toc]

说明

Gateway网关服务本想实现前后端的文件上传及下载功能,但是在实际开发过程中屡屡产生报错,导致一直报错“400 bad request: Required request part 'file' is not present”后端无法解析接收到文件数据,从而导致无法实现前端文件上传及后端接收解析过程,本文就是为了记录成功案例,以及描述本人尝试其他方案的感受,便于其他人吸取经验,排雷。

SpringBoot和SpringCloudGateway项目区别说明

Spring Boot是一套基于Spring框架的微服务框架。
SpringCloudGateway基于webFlux框架实现的
框架不同就导致,之前网上传统的那套controller层方法就不适用,现在分别举例说明

1.SpringBoot的成功案例文件上传代码

pom

<!--文件上传-->
 <dependency>
     <groupId>commons-fileupload</groupId>
     <artifactId>commons-fileupload</artifactId>
     <version>1.3.3</version>
 </dependency>

前端代吗

<p>单文件上传并保存</p>
<form method="post" action="/excel/uploadExcel" enctype="multipart/form-data">
    <p><input type="file" name="file00"></p>
    <p><span th:if="${msg}"></span></p>
    <input type="submit" value="提交">
</form>

Controller代码 重点在:@RequestParam("file00") MultipartFile file

@PostMapping(value = "/uploadExcel")
    public String uploadExcel(@RequestParam("file00") MultipartFile file, Model model) throws IOException {
   
        try {
   
            if(file.isEmpty()){
   
                model.addAttribute("msg","上传失败,请选择文件!");
                return "excelIndex";
            }
            String filename = file.getOriginalFilename();
            //filePath获取的是编译后的路径,而不是项目看到的路径,filePath=/E:/WorkSpace/demo/target/classes/
            String filePath = ResourceUtils.getURL("classpath:").getPath()+"static/oneFile/";
            //避免文件重复覆盖
            String uuid= UUID.randomUUID().toString().replaceAll("-", "");
            //时间戳分类文件
            String time = new SimpleDateFormat("YYYY-MM").format(new Date());
            String realPath = filePath + time + "/" + uuid + "-" + filename;
            System.out.println("realPath:" + realPath);
            //最后保存的路径在这里:target/classes/static/oneFile/2022-02/548881060e3d417a91d87b0a10959077-sop.sql
            File dest = new File(realPath);
            //检测是否存在目录,无,则创建
            if(!dest.getParentFile().exists()){
   
                dest.getParentFile().mkdirs();//新建文件夹 多级目录
            }
            file.transferTo(dest);//文件写入
        } catch (IOException e) {
   
            e.printStackTrace();
        }
        model.addAttribute("msg","文件上传成功!");
        return "hello";
    }

2.SpringCloudGateway的成功案例文件上传代码

Controller代码

重点区别在:

1.注解中配置consumes = MediaType.MULTIPART_FORM_DATA_VALUE
2.形参采用@RequestPart("file") FilePart filePart,而不是传统的@RequestParam("file00") MultipartFile file,这是他两的区别

备注说明:

1.使用RequestPart来接收,得到的是FilePart
2.FilePart的content是Flux,可以使用DataBufferUtils写到文件或者直接使用transferTo写入到文件
详情可查看该文章了解 ->: SPRING WEBFLUX 前后端分离 文件上传
```java
import org.springframework.core.io.buffer.DataBufferUtils;
import org.springframework.http.MediaType;
import org.springframework.http.codec.multipart.FilePart;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;

import java.io.IOException;
import java.nio.channels.AsynchronousFileChannel;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;

@PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public Mono requestBodyFlux(@RequestPart("file") FilePart filePart) throws IOException {
System.out.println(filePart.filename());
Path tempFile = Files.createFile(Paths.get("D:\tmp\"+filePart.filename()));

    //方法一
  AsynchronousFileChannel channel =
          AsynchronousFileChannel.open(tempFile, StandardOpenOption.WRITE);
  DataBufferUtils.write(filePart.content(), channel, 0)
          .doOnComplete(() -> {
              System.out.println("finish");
          })
          .subscribe();

    //方法二
    //filePart.transferTo(tempFile.toFile());

  System.out.println(tempFile.toString());
  return Mono.just(filePart.filename());

}
```

网上其他方案

说明:
1.针对前端代码格式书写错误导致
2.针对后端代码编写Filter过滤器文件进行解析
3.注入Bean方式 或者xml配置xxResolver解析器进行文件解析
下面方法直接拷贝可能会报错,里面某些类没有标注引用,会报错找不到或者调用还是报 "400 bad request: Required request part 'file' is not present"

其他方案1:配置filter

Spring-Cloud-Gateway获取multipart/form-data时无法正常获取

其他方案2:配置filter

SpringCloud-Gateway对multipart/form-data等其他POST请求类型的body体进行多次打开

其他方案3:注入Bean或者xml配置xxResolver解析器进行文件解析

Spring Cloud Gateway 之获取请求体(Request Body)的几种方式

其他方案4:既然MultipartFile后端接收不到,那就采用把上传文件进行Base64编码,通过json格式传给后台。

GATEWAY网关上传文件问题

其他方案5:修改前端vue

Vue上传通过“服务端签名后直传”上传文件到阿里云 报错 400 Bad Request

其他方案6:修改前端vue

vue put 提交 400 Bad Request(有时候可以提交成功)

其他方案7:xml配置xxResolver解析器进行文件解析

springMVC 文件上传 HTTP Status 400 – Bad Request

image.png

重要信息

image.png
image.png
image.png

目录
相关文章
|
6月前
|
小程序
内网环境中ruoyi若依实现微信小程序授权登录解决办法
内网环境中ruoyi若依实现微信小程序授权登录解决办法
409 0
|
23天前
|
前端开发 JavaScript Java
SpringCloudGateway网关服务实现文件上传功能
SpringCloudGateway网关服务实现文件上传功能
41 1
|
6月前
|
负载均衡 Java 网络架构
在SpringCloud2023中快速集成SpringCloudGateway网关
本文主要简单介绍SpringCloud2023实战中SpringCoudGateway的搭建。后续的文章将会介绍在微服务中使用熔断Sentinel、鉴权OAuth2、SSO等技术。
156 2
在SpringCloud2023中快速集成SpringCloudGateway网关
|
3月前
|
小程序 JavaScript Java
微信小程序+SpringBoot接入后台服务,接口数据来自后端
这篇文章介绍了如何将微信小程序与SpringBoot后端服务进行数据交互,包括后端接口的编写、小程序获取接口数据的方法,以及数据在小程序中的展示。同时,还涉及到了使用Vue搭建后台管理系统,方便数据的查看和管理。
微信小程序+SpringBoot接入后台服务,接口数据来自后端
|
4月前
|
JSON 前端开发 Java
SpringCloud怎么搭建GateWay网关&统一登录模块
本文来分享一下,最近我在自己的项目中实现的认证服务,目前比较简单,就是可以提供一个公共的服务,专门来处理登录请求,然后我还在API网关处实现了登录拦截的效果,因为在一个博客系统中,有一些地址是可以不登录的,比方说首页;也有一些是必须登录的,比如发布文章、评论等。所以,在网关处可以支持自定义一些不需要登录的地址,一些需要登录的地址,也可以在网关处进行校验,如果未登录,可以返回JSON格式的出参,前端可以进行相关处理,比如跳转到登录页面等。
126 4
|
5月前
|
搜索推荐 前端开发 JavaScript
SpringBoot静态资源访问控制和封装集成方案
该文档描述了对基于SpringBoot的项目框架进行优化和整合的过程。原先采用前后端分离,后端兼做前端,但随着项目增多,升级维护变得复杂。因此,决定整合后台管理页面与后端代码,统一发布。设计上,框架包含后台管理资源,项目则配置具体业务页面,项目可通过覆盖框架资源实现个性化。关键步骤包括:自定义静态资源访问路径、解决图标与字体文件访问问题、设定自定义欢迎页面和页面图标,以及确保项目能正确访问框架静态资源。通过扫描jar包、解压和拷贝资源到项目目录,实现了框架静态资源的动态加载。此外,调整静态资源访问优先级,保证正确加载。最终实现支持jar和war包的项目结构优化。
112 4
|
5月前
|
JSON Java API
技术笔记:springboot项目使用拦截器实现一个简单的网关请求透传
技术笔记:springboot项目使用拦截器实现一个简单的网关请求透传
239 0
|
6月前
|
微服务
SpringCloud-Config服务端微服务从自己的Gitee上获取配置内容配置读取规则
SpringCloud-Config服务端微服务从自己的Gitee上获取配置内容配置读取规则
57 0
|
6月前
|
Java
springboot WebMvcConfigurer详解自定义配置请求静态资源
springboot WebMvcConfigurer详解自定义配置请求静态资源
161 0
下一篇
无影云桌面