具有 Spring WebFlux 的 RestController:所需参数不存在
RestController with Spring WebFlux :Required parameter is not present
我用SpringWebFlux写了一个Rest Controller Demo,不能运行正确,源码如下:
@RestController
public class Demo{
@PostMapping(value = "test2")
public Integer getHashCode(@RequestParam("parameters") String parameters){
return parameters.hashCode();
}
}
我用Postman测试了一下,返回:
{
"timestamp": "2018-05-07T07:19:05.303+0000",
"path": "/test2",
"status": 400,
"error": "Bad Request",
"message": "Required String parameter 'parameters' is not present"
}
依赖项:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
I wrote the same controller demo with Spring boot(v2.0.1.RELEASE), it can run correctly. Why can't it run correctly in Spring Webflux?
与 described in the reference documentation 一样,基于 Servlet 的应用程序(Spring MVC)和 Spring WebFlux 在请求参数方面存在细微的行为差异。
在SpringWebFlux中,@RequestParam
只会绑定查询参数。在您的情况下,您的 HTTP 请求未提供此类查询参数,并且您的方法签名未将其标记为可选。
查看您的 Postman 屏幕截图,您似乎打算将 HTTP 表单数据绑定到该参数,那么您应该看看 command objects。
您可以 post 将请求作为 x-www-form-urlencoded
而不是表单数据吗?我想 Spring webflux 只接受作为查询参数而不是表单数据的请求参数。
更新:
我只是用 webflux 和 java 10 尝试了相同的代码。我可以清楚地得到正确的响应。所以 webflux 和表单数据没有任何影响。
正如@brian-clozel 在他的回答中提到的 Spring WebFlux 目前不支持 @RequestParam
从表单数据和多部分进行绑定(有一个未解决的问题 SPR-16190).
另一种方法可能是注入 ServerWebExchange
并访问它的 getFormData()
:
@PostMapping(value = "test2")
public Mono<Integer> getHashCode(ServerWebExchange exchange){
return exchange.getFormData().map(formData -> {
if (formData.containsKey("parameters")) {
return formData.getFirst("parameters").hashCode();
} else {
throw new ServerWebInputException("Required parameter 'parameters' is not present");
}
});
}
(但老实说,使用 @ModelAttribute
和专用模型 class 处理表单数据的方法看起来容易得多)
我用SpringWebFlux写了一个Rest Controller Demo,不能运行正确,源码如下:
@RestController
public class Demo{
@PostMapping(value = "test2")
public Integer getHashCode(@RequestParam("parameters") String parameters){
return parameters.hashCode();
}
}
我用Postman测试了一下,返回:
{
"timestamp": "2018-05-07T07:19:05.303+0000",
"path": "/test2",
"status": 400,
"error": "Bad Request",
"message": "Required String parameter 'parameters' is not present"
}
依赖项:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
I wrote the same controller demo with Spring boot(v2.0.1.RELEASE), it can run correctly. Why can't it run correctly in Spring Webflux?
与 described in the reference documentation 一样,基于 Servlet 的应用程序(Spring MVC)和 Spring WebFlux 在请求参数方面存在细微的行为差异。
在SpringWebFlux中,@RequestParam
只会绑定查询参数。在您的情况下,您的 HTTP 请求未提供此类查询参数,并且您的方法签名未将其标记为可选。
查看您的 Postman 屏幕截图,您似乎打算将 HTTP 表单数据绑定到该参数,那么您应该看看 command objects。
您可以 post 将请求作为 x-www-form-urlencoded
而不是表单数据吗?我想 Spring webflux 只接受作为查询参数而不是表单数据的请求参数。
更新: 我只是用 webflux 和 java 10 尝试了相同的代码。我可以清楚地得到正确的响应。所以 webflux 和表单数据没有任何影响。
正如@brian-clozel 在他的回答中提到的 Spring WebFlux 目前不支持 @RequestParam
从表单数据和多部分进行绑定(有一个未解决的问题 SPR-16190).
另一种方法可能是注入 ServerWebExchange
并访问它的 getFormData()
:
@PostMapping(value = "test2")
public Mono<Integer> getHashCode(ServerWebExchange exchange){
return exchange.getFormData().map(formData -> {
if (formData.containsKey("parameters")) {
return formData.getFirst("parameters").hashCode();
} else {
throw new ServerWebInputException("Required parameter 'parameters' is not present");
}
});
}
(但老实说,使用 @ModelAttribute
和专用模型 class 处理表单数据的方法看起来容易得多)