【问题标题】:WebFlux: Issues uploading fileWebFlux:上传文件的问题
【发布时间】:2019-03-12 13:43:08
【问题描述】:

我正在开发一个客户端来使用 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

【问题讨论】:

  • 我有类似的问题(同样的错误),但是当我使用RestTemplate 发布时,从curl 提交文件就可以了。我能注意到的唯一区别是curl 使用Expect: 100 redirect 标头,而RestTemplate 使用Connection: keep-alive
  • 您好,我使用您的客户请求我的服务,并且效果很好,解决方案在这里stackoverflow.com/questions/53778890/…

标签: java spring-webflux


【解决方案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()
}

【讨论】:

    【解决方案2】:

    这对我有用

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

    【讨论】:

      猜你喜欢
      • 2022-01-21
      • 1970-01-01
      • 1970-01-01
      • 2010-10-17
      相关资源
      最近更新 更多