说明
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();
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);
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 前后端分离 文件上传
@PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public Mono<String> 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();
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
|