当前位置: 首页 > 知识库问答 >
问题:

如何在Spring 5.3 WebFlux中将ClientACK主体作为DataBuffer?

田镜
2023-03-14

在弃用WebClient之前。交换我用来获取ClientResponse body作为Flux的方法

在Spring 5.3中,exchange()方法被弃用,我希望按照建议更改实现:

@自5.3以来已弃用,因为可能会泄漏内存和/或连接;请使用{@link#exchange eToMono(Function)}、{@link#exchange eToFlux(Function)};还考虑使用{@link#检索()}...

试图在传递给exchangeToMono的lambda中执行相同的调用,但客户端响应。bodyToFlux(DataBuffer::class.java)始终返回空流量;其他实验(即将身体作为单音字符串)也不能帮助获得身体。

在Spring 5.3中获取客户响应体的标准方法是什么?

我正在寻找一种低级的主体表示:类似于“数据缓冲区”、“字节数组”或“输入流”;避免任何类型的解析/反序列化。

Spring5.3之前:

webClient
    .method(GET)
    .uri("http://somewhere.com")
    .exchange()
    .flatMap { clientResponse ->
       val bodyRaw: Flux<DataBuffer> = clientResponse.bodyToFlux(DataBuffer::class.java) 
       // ^ body as expected
           
       // other operations
    }

Spring后5.3

webClient
    .method(GET)
    .uri("http://somewhere.com")
    .exchangeToMono { clientResponse ->
       val bodyRaw: Flux<DataBuffer> = clientResponse.bodyToFlux(DataBuffer::class.java)
       // ^ always empty flux
           
       // other operations
    }

共有1个答案

史鹏云
2023-03-14

新的exchangeToMono和exchangeToFlux方法期望在回调内部对主体进行解码。有关详细信息,请查看此GitHub问题。

看看您的示例,您可能可以使用更安全的替代方法,即使用bodyToFlux

webClient
        .method(GET)
        .uri("http://somewhere.com")
        .retrieve()
        .bodyToFlux(DataBuffer.class)

或者toEntityFlux如果您需要访问响应详细信息,例如标头和状态

webClient
        .method(GET)
        .uri("http://somewhere.com")
        .retrieve()
        .toEntityFlux(DataBuffer.class)

处理错误

选项1。使用OneErrorResume和句柄WebClient响应异常

webClient
        .method(GET)
        .uri("http://somewhere.com")
        .retrieve()
        .bodyToFlux(DataBuffer.class)
        .onErrorResume(WebClientResponseException.class, ex -> {
            if (ex.getStatusCode().equals(HttpStatus.NOT_FOUND)) {
                // ignore 404 and return empty
                return Mono.empty();
            }

            return Mono.error(ex);
        });

选项2。使用方便的方法访问响应。

webClient
        .method(GET)
        .uri("http://somewhere.com")
        .retrieve()
        .onStatus(status -> status.equals(HttpStatus.NOT_FOUND), res -> {
            // ignore 404 and return empty
            return Mono.empty();
        })
        .bodyToFlux(DataBuffer.class)

这两种方法都可以用于反序列化错误响应,在Spring WebClient出现错误的情况下获取响应主体

 类似资料:
  • 问题内容: 我正在尝试使用类似于以下内容的InputStream来执行POST: 在这种情况下,InputStream来自压缩的tar文件。 张贴InputStream的正确方法是什么? 问题答案: 我在这里想到的唯一解决方案是使用TypeFile类: 和接口(这次没有显式设置Content-Type标头): 使用我自己的TypedInput实现会导致模糊的EOF异常,即使我提供了length()

  • 问题内容: 我有一个MS SQL视图,我想以CSV下载的形式在我的ASPNET Web窗体应用程序中使用。我正在将Entity Framework用于项目中的其他视图和表。启用此下载的最佳方法是什么? 我可以添加一个LinkBut​​ton,其Click处理程序将在视图上进行迭代,将其CSV形式写入磁盘,然后提供该文件。但是,如果可以避免的话,我宁愿不写到磁盘上,因为这涉及到一些其他解决方案可以避

  • 我正在下载带有GET请求的文件。其中有些相当大,所以我希望将它们作为一个流来获取,并在能够处理它们时以块的形式读取字节,而不是在内存中读取整个文件。 WebClient看起来很合适,但我遇到了“UnsupportedMediaTypeException:内容类型'application/octet-stream'不受支持”。 下面是一些简短的示例代码。 这里是堆栈跟踪的一大块。 ...... 我确

  • 我有两个表,在我的Spring代码中是学生和课程。我想创建一个关系表,“获取课程”。我只有学生ID和课程ID。我可以在我的java代码中创建一个具有两个主键的表,但我不能将它们声明为外键。 我尝试了这个解决方案,将两个外键作为主键,但没有成功,我认为其中缺少了一些部分。因此,我尝试了基于此解决方案的方法: (学生实体有id, name, surname)(课程实体有id, Coursename)

  • 我刚刚为游戏塑造了我的角色,这是一个box2d动态身体: 可以给身体添加纹理或精灵吗?或者我把精灵的位置和我身体的位置一样?因此,它将覆盖身体的形状,并像实际的box2d身体一样移动。