Spring WebClient多部分文件上传
Spring WebClient多部分文件上传
一个简单的Spring Boot 2.7.5 WebClient应用程序在400 BAD REQUEST时失败:
var home = "/home/me"; var uploadFile = new File(home+"/upload.csv"); var uploadPath = uploadFile.toPath(); var uploadContent = Files.readString(uploadPath); var multipartBodyBuilder = new MultipartBodyBuilder(); multipartBodyBuilder.part("file", uploadPath); //multipartBodyBuilder.part("file", uploadFile); var mimeMultipartData = multipartBodyBuilder.build(); var configuration = new Configuration(/* ... */); var webClient = WebClient.builder() .baseUrl(_baseUrl(configuration.getEndpoint())) .filters( filters -> { filters.add(authentication(configuration)); if (configuration.capturePackets()) { filters.add(captureRequest()); filters.add(captureResponse()); } }) .build(); MonohttpStatusMono = webClient .post() .uri(URI.create("http://localhost:8080/api/marketplaces/1/holdings/uploads")) .body(BodyInserters.fromMultipartData(mimeMultipartData)) .retrieve() .bodyToMono(HttpStatus.class);
针对Spring Boot 2.7.5多部分文件上传API:
@PostMapping("/uploads") public ResponseEntity> uploads(@RequestParam(value="file", required=true) MultipartFile file) throws IOException { try (InputStream input = file.getInputStream()) { doSomething(input); } return ResponseEntity.ok().build(); }
坏请求异常为:
org.springframework.web.reactive.function.client.WebClientResponseException$BadRequest: 400 Bad Request from POST http://localhost:8080/api/uploads at org.springframework.web.reactive.function.client.WebClientResponseException.create(WebClientResponseException.java:217) Suppressed: The stacktrace has been enhanced by Reactor, refer to additional information below: Error has been observed at the following site(s): *__checkpoint ⇢ 400 from POST http://localhost:8080/api/uploads [DefaultWebClient] Original Stack Trace: at org.springframework.web.reactive.function.client.WebClientResponseException.create(WebClientResponseException.java:217) ...
这个简单的curl请求正常工作:
curl -X POST -v --user "username:password" -H "Content-Type: multipart/form-data" \\ --form [email protected] http://localhost:8080/api/uploads
这个Angular POST也正常工作(未显示身份验证拦截器):
upload(file: File): Observable{ const formData: FormData = new FormData() formData.append('file', file, file.name); const observable: Observable = this._http .post(url, formData) .pipe( // map(response => response), share() );
有没有办法让Spring WebClient API像curl和Angular客户端一样工作的想法?