带有Spring WebFlux的RestController:不存在必需参数

时间:2018-05-07 07:37:03

标签: spring spring-mvc spring-boot spring-webflux

我用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"
}

enter image description here

依赖项:

<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启动(v2.0.1.RELEASE)编写了相同的控制器演示,它可以正常运行。为什么它无法在Spring Webflux中正确运行?

3 个答案:

答案 0 :(得分:1)

作为described in the reference documentation,基于Servlet的应用程序(Spring MVC)和Spring WebFlux在请求参数方面存在轻微的行为差异。

在Spring WebFlux中,@RequestParam只会绑定查询参数。在您的情况下,您的HTTP请求不提供此类查询参数,并且您的方法签名不会将其标记为可选。

查看Postman屏幕截图,看起来您打算将HTTP表单数据绑定到该参数,然后您应该看一下command objects

答案 1 :(得分:0)

您可以将请求发布为x-www-form-urlencoded而不是表单数据吗?我猜Spring webflux只接受查询参数的请求参数,而不是表单数据。

更新 我刚刚尝试了与webflux和java 10相同的代码。我可以清楚地得到正确的响应..所以webflux和表单数据没有任何影响。

post-request

答案 2 :(得分:0)

正如@ 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和用于表单数据的专用模型类的方法要容易得多)