spring-projects / spring-projects/spring-framework

Support for form data via @RequestParam on WebFlux [SPR-16190]

Open
#20,738 16 comments 4 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

in: web type: enhancement
Dominant language
Java
Stars
60.2k
Forks
38.8k
Avg merge
5d 2h
Merged PRs (30d)
27

Description

Miroslav Hrúz opened SPR-16190 and commented

In Spring 4 and Spring 5/ Web (Servlet API) you could write annotated controller method without explicitly say @GetMapping or @PostMapping and without any @RequestParam or @ModelAttribute

@RequestMapping("/get/and/post/form-data-www-urleconded")
public String getAndPost(String param1, String param2) {
	return "Got: param1="+param1+", param2="+param2;
}

Which does except others:

  1. Binds /get/and/post/form-data-www-urleconded to be used with HTTP GET and param1, param2 parameters to HTTP query parameters
  2. Binds /get/and/post/form-data-www-urleconded to be used with HTTP POST form data www-urlencoded and param1, param2 to HTTP POST form data.
  3. Binds /get/and/post/form-data-www-urleconded to be used with HTTP POST multipart data (FormFieldPart) and param1, param2 to HTTP POST multipart data

In Spring WebFlux 5.0.1 it's not working. It works in Spring Web 5.0.1 and in Spring Web 4.x.

The desired use case is when you want to expose REST API for both HTTP GET and POST and you want to simple write the method ones, not to use @GetMapping with appropriate @RequestParam or @PostMapping with @ModelAttribute or @RequestBody. The beauty is not to use any argument annotation at all.

I've attached example projects for spring 4.x, Spring 5.0.1 Web and Spring 5.0.1 WebFlux.

requestMapping_for_post test is failing and should not.

@Test
public void requestMapping_for_get() {
	final WebTestClient client = WebTestClient.bindToController(new TestController()).build();

	final String responseBody = client.get()
			.uri("/get/and/post/form-data-www-urleconded?param1=111&param2=222")
			.exchange()
			.expectStatus().isOk()
			.expectBody(String.class)
			.returnResult().getResponseBody();

	Assert.assertEquals("Got: param1=111, param2=222", responseBody);
}

@Test
public void requestMapping_for_post() {
	final WebTestClient client = WebTestClient.bindToController(new TestController()).build();

	final MultiValueMap<String, String> formData = new LinkedMultiValueMap<>();
	formData.add("param1", "111");
	formData.add("param2", "222");

	final String responseBody = client.post()
			.uri("/get/and/post/form-data-www-urleconded")
			.body(BodyInserters.fromFormData(formData))
			.exchange()
			.expectStatus().isOk()
			.expectBody(String.class)
			.returnResult().getResponseBody();

	Assert.assertEquals("Got: param1=111, param2=222", responseBody);
}

Affects: 5.0.1

Attachments:

Issue Links:

  • #20067 Remove support for "request params" from WebFlux

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by running the named requestMapping_for_get and requestMapping_for_post tests with the WebTestClient and inspect the TestController used by them. Read the linked #20067 discussion to understand the surrounding WebFlux request-parameter decision. Done means the POST form-data test passes without breaking the existing GET query-parameter behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
java, spring
Domain
api, backend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.