带有 Spring WebFlux 的 RestController:必需参数不存在
Posted
技术标签:
【中文标题】带有 Spring WebFlux 的 RestController:必需参数不存在【英文标题】:RestController with Spring WebFlux :Required parameter is not present 【发布时间】:2018-10-16 23:11:21 【问题描述】:我用Spring WebFlux写了一个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>
我用Spring boot(v2.0.1.RELEASE)写了同样的控制器demo,它可以正常运行。为什么在 Spring Webflux 中不能正常运行?
【问题讨论】:
如何在不更改http请求的情况下获得parameters
值?
【参考方案1】:
作为described in the reference documentation,在请求参数方面,基于 Servlet 的应用程序 (Spring MVC) 和 Spring WebFlux 之间存在细微的行为差异。
在 Spring WebFlux 中,@RequestParam
只会绑定查询参数。在您的情况下,您的 HTTP 请求未提供此类查询参数,并且您的方法签名未将其标记为可选。
查看您的 Postman 屏幕截图,您似乎打算将 HTTP 表单数据绑定到该参数,那么您应该改为查看 command objects。
【讨论】:
我把代码改成public Integer getHashCode(@RequestParam("parameters") Optional<String> parameters)
,为什么parameters.isPresent()
返回false?
您是否使用请求 URL 发送了查询参数?
如果我不发送带有请求URL的查询参数,还有其他方法可以正确响应请求吗?
如果您不发送查询参数,那么将该参数声明为可选是正确的方法。
我将其声明为可选,但 parameters.isPresent()
返回 false。【参考方案2】:
您可以将请求发布为 x-www-form-urlencoded
而不是 form-data 吗?我猜 Spring webflux 只接受查询参数而不是表单数据的请求参数。
更新: 我刚刚用 webflux 和 java 10 尝试了相同的代码。我可以清楚地得到正确的响应。所以 webflux 和表单数据没有任何影响。
【讨论】:
也会出现Required String parameter 'parameters' is not present
我试过你的代码,它按预期工作。能否重新检查一下你的代码和tomcat中部署的代码是否相同?
部署在tomcat中可以正常运行。你的代码部署在netty服务器上?@Karthik
Netty started on port(s): 20000
Failed to handle request [POST http://localhost:20000/test2]: Response status 400 with reason "Required String parameter 'parameters' is not present"
否 :( Tomcat。这很奇怪,但我们归零到 Netty?为什么会有不同?什么版本的 netty?你能试试最新的吗?【参考方案3】:
正如@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
和表单数据专用模型类的方法看起来要容易得多)
【讨论】:
以上是关于带有 Spring WebFlux 的 RestController:必需参数不存在的主要内容,如果未能解决你的问题,请参考以下文章
带有 MultipartFile 的 Spring Webflux 415
带有 Spring WebFlux 的 RestController:必需参数不存在
带有 Spring 安全 webflux 的 Angular 6 被 CORS 阻止
Spring Security WebFlux - 带有身份验证的主体
带有 WebFlux 的 Spring Boot 总是在测试中抛出 403 状态
带有 Webflux 的 Spring Boot:请求的资源上不存在“Access-Control-Allow-Origin”标头