我正在开发一个客户端,以使用webflux反应客户端上传文件:
这是我的客户端代码:
private Mono<String> postDocument(String authorization, InputStream content) {
try {
ByteArrayResource resource = new ByteArrayResource(IOUtils.toByteArray(content));
return client.post().uri(DOCS_URI)
.contentType(MediaType.MULTIPART_FORM_DATA)
.header(HttpHeaders.AUTHORIZATION, authorization)
.body(BodyInserters.fromMultipartData("file", resource))
.exchange()
.flatMap(res -> readResponse(res, String.class));
} catch (IOException e) {
throw new RuntimeException(e);
}
}
服务器端代码:
public Mono<ServerResponse> createDocument(ServerRequest request) {
return request.body(toMultipartData())
.flatMap(parts -> Mono.just((FilePart) parts.toSingleValueMap().get("file")))
.flatMap(part -> {
try {
String fileId = IdentifierFactory.getInstance().generateIdentifier();
File tmp = File.createTempFile(fileId, part.filename());
part.transferTo(tmp);
String documentId = IdentifierFactory.getInstance().generateIdentifier();
String env = request.queryParam("env")
.orElse("prod");
CreateDocumentCommand cmd = new CreateDocumentCommand(documentId, tmp, part.filename(), env);
return Mono.fromFuture(cmdGateway.send(cmd));
} catch (IOException e) {
throw new RuntimeException(e);
}
})
.flatMap(res -> ok().body(fromObject(res)));
}
我收到此错误:
java.lang.ClassCastException: org.springframework.http.codec.multipart.SynchronossPartHttpMessageReader$SynchronossPart cannot be cast to org.springframework.http.codec.multipart.FilePart
答案 0 :(得分:1)
我有示例代码,但是在Kotlin中。
希望对您有所帮助。
第一种方法(保存内存)
upload(stream: InputStream, filename: string): HashMap<String, Any> {
val request: MultiValueMap<String, Any> = LinkedMultiValueMap();
request.set("file", MultipartInputStreamFileResource(stream, filename))
return client.post().uri("http://localhost:8080/files")
.contentType(MediaType.MULTIPART_FORM_DATA)
.body(BodyInserters.fromMultipartData(request))
.awaitExchange().awaitBody()
}
class MultipartInputStreamFileResource(inputStream: InputStream?, private val filename: String) : InputStreamResource(inputStream!!) {
override fun getFilename(): String? {
return filename
}
@Throws(IOException::class)
override fun contentLength(): Long {
return -1 // we do not want to generally read the whole stream into memory ...
}
}
第二种方式
//You wrote a file to somewhere in the controller then send the file through webclient
upload(stream: InputStream, filename: string): HashMap<String, Any> {
val request: MultiValueMap<String, Any> = LinkedMultiValueMap();
request.set("file", FileSystemResource(File("/tmp/file.jpg")))
return client.post().uri("http://localhost:8080/files")
.contentType(MediaType.MULTIPART_FORM_DATA)
.body(BodyInserters.fromMultipartData(request))
.awaitExchange().awaitBody()
}
第三种方式
upload(file: Part): HashMap<String, Any> {
val request: MultiValueMap<String, Any> = LinkedMultiValueMap();
request.set("file", file)
return client.post().uri("http://localhost:8080/files")
.contentType(MediaType.MULTIPART_FORM_DATA)
.body(BodyInserters.fromMultipartData(request))
.awaitExchange().awaitBody()
}
答案 1 :(得分:0)
这对我有用
MultipartBodyBuilder bodyBuilder = new MultipartBodyBuilder();
bodyBuilder.part("file", new ClassPathResource("/bulk_upload/test.xlsx"));
List<DataFileAdjustment> list = webClient.post().uri("/bulk").accept(MediaType.APPLICATION_JSON)
.body(BodyInserters.fromMultipartData(bodyBuilder.build()))
.exchange()
.expectStatus().isOk()