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

Spring反应式 Web 应用程序 POST 请求正文丢失

方坚壁
2023-03-14

我参与了一个小型测试项目,以检查Spring Reactive Web应用程序实际上是如何与MongoDB一起工作的。

我遵循手册https://docs.spring.io/spring/docs/5.0.0.M4/spring-framework-reference/html/web-reactive.html

它指出我可以在控制器中处理POST请求,例如:

@PostMapping("/person")
    Mono<Void> create(@RequestBody Publisher<Person> personStream) {
        return this.repository.save(personStream).then();
    }

虽然这似乎不起作用。这里是我实现的控制器:

https://github.com/pavelmorozov/reactor-poc/blob/master/src/main/java/com/springreactive/poc/controller/BanquetHallController.java

它只有一个POST映射,非常简单:

@PostMapping("/BanquetHall")
    Mono<Void> create(@RequestBody Publisher<BanquetHall> banquetHallStream) {
        return banquetHallRepository.insert(banquetHallStream).then();
    }

每次我发出带有 curl 的 POST 时都会调用它:

curl -v -XPOST -H "Content-type: application/json" -d '{"name":"BH22"}' 'http://localhost:8080/BanquetHall'
Note: Unnecessary use of -X or --request, POST is already inferred.
*   Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 8080 (#0)
> POST /BanquetHall HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.47.0
> Accept: */*
> Content-type: application/json
> Content-Length: 15
> 
* upload completely sent off: 15 out of 15 bytes
< HTTP/1.1 200 OK
< content-length: 0
< 
* Connection #0 to host localhost left intact

我看到新对象存储在mongoDB中,但它们不包含数据。为了调试,我构建了简单的订阅者,以查看实际作为请求正文传递给控制器的数据:

Subscriber s = new Subscriber() {
    @Override
    public void onSubscribe(Subscription s) {
        logger.info("Argument: "+s.toString());
    }
    @Override
    public void onNext(Object t) {
        logger.info("Argument: "+t.toString());

    }
    @Override
    public void onError(Throwable t) {
        logger.info("Argument: "+t.toString());
    }
    @Override
    public void onComplete() {
        logger.info("Complete! ");
    }
};
banquetHallStream.subscribe(s);

现在我看到订阅后错误方法调用。可投掷状态正文缺失:

Here error string:
Request body is missing: reactor.core.publisher.Mono<java.lang.Void> com.springreactive.poc.controller.BanquetHallController.create(org.reactivestreams.Publisher<com.springreactive.poc.domain.BanquetHall>)

为什么请求体是空的?

同样值得一提的是:由于我对所有这些反应式的东西都不熟悉,在不手动实现订阅者的情况下,调试发布者/订阅者是否有更好的方法?

更新我更新了POST处理程序方法说明,它将请求正文作为字符串对象传递:

Mono<Void> create(@RequestBody String banquetHallStream)

那幺这不是一个“反应”,对不对?字符串不是反应性的,因为发布者应该是。。。

共有1个答案

寿意远
2023-03-14

我也遇到了同样的问题,通过将< code>@ResponseStatus放在方法上,我解决了这个问题。下面是方法控制器的样子:

@ResponseStatus(HttpStatus.CREATED)
@PostMapping(value = "/bulk", consumes = APPLICATION_STREAM_JSON_VALUE)
public Mono<Void> bulkInsert(@RequestBody Flux<Quote> quotes) {
    return quoteReactiveRepository.insert(quotes).then();
}

我正在使用< code>WebClient向该endpoint发出请求:

webClient.post()
        .uri("/quotes/bulk")
        .contentType(MediaType.APPLICATION_STREAM_JSON)
        .body(flux(), Quote.class)
        .retrieve()
        .bodyToMono(Void.class).block();

测试语言:org.springframework.boot:spring-boot-starter-webflux:2.1.0.RELEASE

 类似资料:
  • 我正在研究访问HTTP请求和响应体的最佳方式,以便在Spring反应式应用程序中进行跟踪。 对于以前的版本,我们已经利用Servlet过滤器和Servlet请求包装器来使用传入请求的输入流,并保存其副本,以便异步处理跟踪(我们将其发送给Elasticsearch)。 但对于一个Spring反应式应用程序(使用webflux),我想知道在解码之前访问请求的最合适方式是什么。有什么想法吗?

  • 这是我的路由器 这是终端错误 正在端口3090上侦听。。。。。(节点:7764)未经处理的PromisejectionWarning:TypeError:无法读取/Users/macbook/Desktop/node project/server/routes/api/posts上未定义的属性“text”。js:19:24在ProcessTicks和Rejections(internal/proc

  • 我希望我的REST API在存在异常和参数类型不匹配时抛出异常。以下是我的请求对象。 在上面的情况下,当一个请求违反这个字符串要求时,应该引发异常(向订阅类型提供一个整数值)。我还需要对无效字符进行验证,如*、-、 我的控制器看起来像这样。 我正在使用@Valid注释,并且我已经包含了Hibernate验证器的maven依赖项 但问题是,它不验证我的输入,也不接受订阅类型和caseId的整数值。

  • 问题内容: 我有一个非常简单的应用程序(没有Spring Boot)。我已经实现了和控制器方法。该方法效果很好。但是,POST正在抛出。复制步骤如下 ServiceController. java AppConfig.java AppInitializer.java 该代码在这里可用: 这将旋转嵌入式tomcat。 现在你可以卷曲以下内容 工作良好 但 引发415不支持的MediaType 问题答

  • 我面临的问题是,有一个服务,我必须调用,这是一个传统的Spring启动应用程序,而不是反应性的! 下面是一个示例endpoint,它接近上述遗留系统的想法: 我知道我不能用这个来实现真正的反应性善,有没有一个快乐的非阻塞和阻塞的媒介我可以在这里实现? 谢谢

  • 我试图以一种干净的方式构建应用程序的体系结构。我想我可以在Netty中做到这一点,因为它是一个著名的java网络框架选项。 我有连接到Netty服务器的设备(通过GPRS的TCP)。假设它们都是永久连接的(保持存活),有几种情况我需要用这个架构来描述: 情况1:设备可以向Netty发送消息,并且Netty响应该消息 情况2:设备可以向Netty发送消息,并且Netty对该消息做出响应,但是Nett