SpringCloudGateway閘道器服務實現檔案上傳功能

刘大猫26發表於2024-11-06

@

目錄
  • 說明
  • SpringBoot和SpringCloudGateway專案區別說明
  • 1.SpringBoot的成功案例檔案上傳程式碼
    • pom
    • 前端代嗎
    • Controller程式碼 重點在:@RequestParam("file00") MultipartFile file
  • 2.SpringCloudGateway的成功案例檔案上傳程式碼
    • Controller程式碼
  • 網上其他方案
    • 其他方案1:配置filter
    • 其他方案2:配置filter
    • 其他方案3:注入Bean或者xml配置xxResolver解析器進行檔案解析
    • 其他方案4:既然MultipartFile後端接收不到,那就採用把上傳檔案進行Base64編碼,透過json格式傳給後臺。
    • 其他方案5:修改前端vue
    • 其他方案6:修改前端vue
    • 其他方案7:xml配置xxResolver解析器進行檔案解析

說明

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

會議詳情

重要資訊

  • 大會官網:https://ais.cn/u/vEbMBz

大會介紹

第三屆教育科學與社會文化國際學術會議(ESSC 2024)定於2024年12月27-29日在中國成都舉行。會議旨在為從事“教育科學”與“社會文化”研究的專家學者提供一個共享科研成果和前沿技術,瞭解學術發展趨勢,拓寬研究思路,加強學術研究和探討,促進學術成果產業化合作的平臺。大會誠邀國內外高校、科研機構專家、學者,企業界人士及其他相關人員參會交流。

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 前後端分離 檔案上傳

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

		//方法二
		//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

相關文章