The behavior of @ModelAttribute in Web MVC and WebFlux is different.

Except for #26856, the HTTP GET parameter cannot be bound normally.

In WebFlux and Web MVC 5.3.4 :

@RestController
@SpringBootApplication
public class MyApp  {

    public static void main(String[] args) {
        SpringApplication.run(MyApp.class);
    }

    @GetMapping("/echo")
    public String echo(@ModelAttribute("msg") String msg) {
        return msg;
    }
}

when I call http://localhost:8080/echo?msg=hello, I get ` for WebFlux buthello` for Web MVC.

Comment From: sbrannen

I've edited your comment to improve the formatting. You might want to check out this Mastering Markdown guide for future reference.

Comment From: sbrannen

Out of curiosity, why are you using @ModelAttribute for a String?

Comment From: aoyvx

Out of curiosity, why are you using @ModelAttribute for a String?

I didn't use @ModelAttribute on string in my work.It's just that when I was learning spring, I found that webflux and webmvc have some behavioral differences.Webmvc will handle UrlParam, but Webflux will not, so this question was raised. This is the first time I put forward issues in GitHub. Maybe it's bad. If it puzzles you, I'm sorry.

Comment From: sbrannen

I didn't use @ModelAttribute on string in my work.It's just that when I was learning spring, I found that webflux and webmvc have some behavioral differences.Webmvc will handle UrlParam, but Webflux will not, so this question was raised.

Thanks for providing the explanation.

This is the first time I put forward issues in GitHub.

Indeed it is... your first GitHub issue ever. Congratulations!

Maybe it's bad. If it puzzles you, I'm sorry.

Oh, no. It's not bad at all. I was merely wondering what your use case was for using @ModelAttribute with a simple type like a String as opposed to a custom type like an Order, User, etc.

In any case, we will investigate the cause for the different behavior.

Comment From: rstoyanchev

@aoyvx, this is an extra feature in Spring MVC where the model attribute can be loaded through a converter. A typical example might look like this:

@PostMapping("/{account}")
public String update(@Valid @ModelAttribute("account") Account account, BindingResult result) {
   // ...
}

Note that the model attribute name "account" matches the name of a request value (in this case a path variable). When this is the case and there is a Converter from String to Account, it is used to load the model attribute rather than instantiating it. The same also works for request parameters as in your case.

I have realized that this not documented in the reference docs, which we can address. The same feature currently does not exist in WebFlux.