首页 > 解决方案 > 使用 Spring WebFlux 从 S3 PutRequest 读取和解析数据

问题描述

我有一个存根设置来处理与 AWS S3 存储桶交互的测试。(自定义)存根实现使用 Spring WebFlux 来响应例如 S3 put-requests。

最近我被迫更改我的 S3 实现以使用InputStream而不是实际文件作为输入。我现在的问题是我的存根实现在传递 InputStream 而不是文件时没有产生预期的结果。

我的存根目前是这样实现的:

RouterFunction<ServerResponse> putS3Object() {
    return RouterFunctions.route(PUT("/S3/MyBucket/{filename}").and(accept(TEXT_PLAIN))) { ServerRequest request ->
        return request.bodyToMono(String)
                .doOnSuccess { s3Stubs.registerPutObject(request.pathVariable("filename"), it) }
                .flatMap { response -> ServerResponse.ok().build() }
    }
}

参数中传递的字符串s3Stubs.registerPutObject包含it预期值“Hello World”。

现在,当我使用 InputStream 作为 S3 API 的参数而不是文件时,it参数不再是“人类可读的”。它包含如下数据:18;chunk-signature=c27c7fa381b8aa2824e8487979d2d0e9ded04dd3 ..... 0;chunk-signature=db7e8b1bacc57da0d410ee116- 我期望相同的结果“Hello World”。

我不确定这是否与我的 Webflux 实现有关,或者与实际文件相比,S3 如何处理 InputStreams。

InputStream在放入真实世界的 S3 存储桶时,使用完全相同的 S3 实现...

标签: springamazon-s3spring-webflux

解决方案


查看 AWS S3 开发工具包,该InputStream变体似乎还需要一些元数据,其中应包含内容的长度和 base64 哈希。这可能就是您在这里看到的被发送到您的存根的内容。

bodyToMono(String.class)真正将整个请求正文缓冲在内存中并将其解码为字符串。Encoder对于其他有线格式,Spring 依赖于Decoder实现(有一种用于 JSON,另一种用于 protobuf)。编写自己的代码是可能的,但非常复杂,并且在编写存根实现时可能不是最佳选择。

如果您想真正存根,您应该接受 S3 客户端发送给您的任何内容,或者阅读该客户端使用的实际线路格式。

现在关于您当前的实现:您似乎正在尝试在doOnXYZ方法中执行 I/O 操作。这些方法被称为“副作用”方法,因为它们的目标是打印一些日志或记录一些状态,但不做与 I/O 相关的工作——而且绝对不会阻塞 I/O。Reactor 提供了封装阻塞代码的方法


推荐阅读