【发布时间】:2020-03-29 11:59:48
【问题描述】:
总的来说,我是 Webflux 和 Spring 的新手,在设置处理 POST 请求的简单服务器时遇到了麻烦:
WebfluxtestApplication.java
package com.test.webfluxtest;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;
@SpringBootApplication
@RestController
public class WebfluxtestApplication {
public static void main(String[] args) {
SpringApplication.run(WebfluxtestApplication.class, args);
}
@PostMapping
public Mono<Person> processPerson(@RequestBody Mono<Person> personMono){
Person person = personMono.block();
person.setAge(42);
return Mono.just(person);
}
}
Person 如下:
Person.java
package com.test.webfluxtest;
import com.fasterxml.jackson.annotation.JsonProperty;
public class Person {
private String name;
private int age;
public Person(@JsonProperty String name, @JsonProperty int age){
this.name = name;
this.age = age;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return this.name + " " + this.age;
}
}
但是,当我发送 POST 请求时,我收到了 java.lang.IllegalStateException。更具体地说,这里是堆栈跟踪的顶部:
java.lang.IllegalStateException: In a WebFlux application, form data is accessed via ServerWebExchange.getFormData().
at org.springframework.web.reactive.result.method.annotation.AbstractMessageReaderArgumentResolver.readBody(AbstractMessageReaderArgumentResolver.java:158) ~[spring-webflux-5.2.1.RELEASE.jar:5.2.1.RELEASE]
Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException:
Error has been observed at the following site(s):
|_ checkpoint ? HTTP POST "/" [ExceptionHandlingWebHandler]
Stack trace:
at org.springframework.web.reactive.result.method.annotation.AbstractMessageReaderArgumentResolver.readBody(AbstractMessageReaderArgumentResolver.java:158) ~[spring-webflux-5.2.1.RELEASE.jar:5.2.1.RELEASE]
at org.springframework.web.reactive.result.method.annotation.AbstractMessageReaderArgumentResolver.readBody(AbstractMessageReaderArgumentResolver.java:126) ~[spring-webflux-5.2.1.RELEASE.jar:5.2.1.RELEASE]
at org.springframework.web.reactive.result.method.annotation.RequestBodyMethodArgumentResolver.resolveArgument(RequestBodyMethodArgumentResolver.java:64) ~[spring-webflux-5.2.1.RELEASE.jar:5.2.1.RELEASE]
at org.springframework.web.reactive.result.method.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:123) ~[spring-webflux-5.2.1.RELEASE.jar:5.2.1.RELEASE]
at org.springframework.web.reactive.result.method.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:200) ~[spring-webflux-5.2.1.RELEASE.jar:5.2.1.RELEASE]
at org.springframework.web.reactive.result.method.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:137) ~[spring-webflux-5.2.1.RELEASE.jar:5.2.1.RELEASE]
at org.springframework.web.reactive.result.method.annotation.RequestMappingHandlerAdapter.lambda$handle$1(RequestMappingHandlerAdapter.java:200) ~[spring-webflux-5.2.1.RELEASE.jar:5.2.1.RELEASE]
at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:44) ~[reactor-core-3.3.0.RELEASE.jar:3.3.0.RELEASE]
问题似乎是我直接使用@RequestBody 标签而不是通过ServerWebExchange 访问表单数据。但是,我在网上看到了多个示例,其中 @RequestBody 与 WebFlux 一起使用没有任何问题。例如the framework documentation of Spring itself。
在使用标签产生IllegalStateExceptions(如here)的情况下似乎存在类似问题,但有不同的异常消息。
我使用spring-boot初始化器创建项目的成绩文件,但我自己没有更改。
有人知道问题是什么以及我该如何解决吗?
编辑
感谢 Aviad Levy,我能够找到问题所在。
也就是说,POST 请求的格式不正确,因为正文是在 url 中编码发送的。为了使它工作,我必须确保请求正文是一个 JSON 对象,并且 Content-Type 标头设置为 application/json。
我仍然对为什么使用错误的格式会引发带有特定消息的异常感到困惑。
【问题讨论】:
-
您能否将导致此错误的请求添加到您的帖子中?
-
@AviadLevy 您可能已经看到了它,但错误确实在发布请求中。我编辑了我的帖子来解释这个问题。
-
很高兴读到你想通了。
-
@RequestBody Mono<Person> personMono导致您的错误,您正在接受Mono<Person>当您发送带有请求的正文并且您没有指定 Content-Type 时,spring 默认假设它是 form您正在发送的数据,因为您正在发布带有正文的内容。因此,当它尝试调用ServerWebExchange.getFormData()时,您会得到一个非法状态异常,并且该函数会因该异常而崩溃。
标签: spring spring-boot spring-webflux illegalstateexception