Spring webflux 不会使用 @ModelAttribute 从路径变量填充自定义对象

Posted

技术标签:

【中文标题】Spring webflux 不会使用 @ModelAttribute 从路径变量填充自定义对象【英文标题】:Spring webflux doesn't populate custom object from path variables with @ModelAttribute 【发布时间】:2019-04-14 16:32:58 【问题描述】:

我正在尝试调整一个与 Spring MVC 配合良好但与 Spring WebFlux 具有不同行为的应用程序

这是我使用 Spring Boot 5 - Spring MVC 的代码:

控制器:

@RestController
public class MyRestController 

    @GetMapping("/test/id/label")
    public ResponseEntity<Payload> test(@ModelAttribute Payload payload) 
        return new ResponseEntity<>(payload,HttpStatus.OK);
    

Payload 对象:

public class Payload 

    @NotNull
    private int id;

    private String label;

    public Payload() 

    public String getLabel() 
        return label;
    

    public void setLabel(String label) 
        this.label = label;
    

    public int getId() 
        return id;
    

    public void setId(int id) 
        this.id = id;
    

我的 pom.xml

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.1.0.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
</dependencies>

我没有编写任何自定义转换器,Spring 自动填充我的有效负载对象,一切都很好。

当我打电话时:

http://localhost:8080/test/25/helloWorld

回应是

"id":25,"label":"helloWorld"

然后,我只更改我的 pom.xml,从 web 切换到 webflux:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.1.0.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-webflux</artifactId>
    </dependency>
</dependencies>

我的有效负载对象不再填充。

当我打电话时:

http://localhost:8080/test/25/helloWorld

回应是

"id":0,"label":null

我知道我可以编写一个转换器并将其注册到@ControllerAdvice,但我无法想象没有一个自动化的解决方案可以让它再次工作,因为它一直与 Spring Web 一起工作。

有人遇到过和我一样的问题吗?

谢谢,

朱利安

【问题讨论】:

【参考方案1】:

Spring WebFlux reference documentation about @ModelAttribute 没有提及 URI 路径变量,这与 the same section in the reference documentation for Spring MVC 不同:

上面的Pet实例解析如下:

如果已使用模型添加,则来自模型。 从 HTTP 会话使用 @SessionAttributes。 从通过转换器传递的 URI 路径变量(见下 示例)。 来自默认构造函数的调用。 从“主构造函数”的调用中调用 匹配 Servlet 请求参数。参数名称已确定 通过 JavaBeans @ConstructorProperties 或通过运行时保留 字节码中的参数名称。

此时这是预期的行为,该选择背后可能有充分的理由或限制。 Feel free to open an enhancement request in Spring Framework for that.

【讨论】:

谢谢布赖恩,我会这样做的!

以上是关于Spring webflux 不会使用 @ModelAttribute 从路径变量填充自定义对象的主要内容,如果未能解决你的问题,请参考以下文章

深入剖析 Spring WebFlux

Spring5---新特性(WebFlux)

Spring-WebFlux使用,一文带你从0开始学明白Spring-WebFlux,学明白响应式编程

Spring Boot (十四): 响应式编程以及 Spring Boot Webflux 快速入门

Spring @Async 与 Spring WebFlux

技术使用 Spring 5 的 WebFlux 开发反应式 Web 应用