使用 Webflux 和 Spring 使用 Google 云存储启动的多部分文件上传的 UnsupportedOperationException

UnsupportedOperationException with MultiPart file upload using Webflux and Spring Boot with Google Cloud Storage

当使用替代 FileSystemFilePart.transferTo 时,我看到在分段文件上传期间抛出 UnsupportedOperationException

似乎 Spring 使用的 SynchronossFilePart 实现在处理数据时切换到不同的 FileSystemProvider。有什么方法可以防止这种情况并强制 Spring 仅使用所需的文件系统?

下面提供了一个片段,它演示了使用 google-cloud-nio 作为文件系统的问题,它试图将上传的文件保存到 google 云存储。

我正在使用 Spring Boot 2.1.3

    @PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public Mono<Void> multipartUpload( final @RequestPart("file") FilePart filePart
    ) {

        FileSystem fileSystem = CloudStorageFileSystem.forBucket("my-bucket");

        // Code snippet that demonstrates connectivity to GCP is okay
        //try {
        //    Files.write(fileSystem.getPath("successful-file"), "Just here to prove this works, this data is written to the bucket successfully, can be removed".getBytes());
        //} catch (IOException e) {
        //    e.printStackTrace();
        //}
        return filePart.transferTo(fileSystem.getPath("failed-file"));
    }

相关堆栈跟踪:

java.lang.UnsupportedOperationException: null
    at java.base/java.nio.file.spi.FileSystemProvider.newFileChannel(FileSystemProvider.java:524)
    at java.base/java.nio.channels.FileChannel.open(FileChannel.java:292)
    at java.base/java.nio.channels.FileChannel.open(FileChannel.java:345)
    at org.springframework.http.codec.multipart.SynchronossPartHttpMessageReader$SynchronossFilePart.transferTo(SynchronossPartHttpMessageReader.java:334)

CloudStorageFileSystemProvider 扩展了 java nio class FileSystemProvider 这是异常的来源。

CloudStorageFileSystemProvider 不会覆盖 newFileChannel 方法和 documentation class 状态的默认行为:

The default provider is required to support the creation of file channels. When not overridden, the default implementation throws UnsupportedOperationException.

这看起来像是 google-cloud-nio 库的问题,尽管可以改进 webflux 实现,以免依赖其他提供商缺少的实现。

更新: 看起来 google-cloud-nio 有 released newFileChannel 方法的实现,从版本 0.88.0-alpha 开始应该可以解决这个问题