Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for MultiValueMap elements in web data binding #26297

Closed
MHajoha opened this issue Dec 18, 2020 · 3 comments
Closed

Support for MultiValueMap elements in web data binding #26297

MHajoha opened this issue Dec 18, 2020 · 3 comments
Assignees
Labels
in: core Issues in core modules (aop, beans, core, context, expression) in: web Issues in web modules (web, webmvc, webflux, websocket) type: enhancement A general enhancement
Milestone

Comments

@MHajoha
Copy link

MHajoha commented Dec 18, 2020

Affects: spring-web 5.2.11


Given a controller like the following:

import javax.annotation.Nullable;

import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/path")
public class MyController {

	private static class MyCriteria {

		@Nullable
		private String param1;

		@Nullable
		private MultiValueMap<String, String> otherParams;

		// getters and setter omitted
	}

	@GetMapping
	public void getByCriteria(MyCriteria criteria) {
		// body
	}
}

I would expect a GET request to /path?param1=a&otherParams[otherParam]=b to cause an instance of MyCriteria with param1 = "a" and otherParams = {"otherParam": ["b"]} to be passed in.

Instead, the following exception is thrown:

java.lang.ClassCastException: class java.lang.String cannot be cast to class java.util.List (java.lang.String and java.util.List are in module java.base of loader 'bootstrap')
	at org.springframework.util.LinkedMultiValueMap.put(LinkedMultiValueMap.java:42)
	at org.springframework.beans.AbstractNestablePropertyAccessor.processKeyedProperty(AbstractNestablePropertyAccessor.java:371)
	at org.springframework.beans.AbstractNestablePropertyAccessor.setPropertyValue(AbstractNestablePropertyAccessor.java:275)
	at org.springframework.beans.AbstractNestablePropertyAccessor.setPropertyValue(AbstractNestablePropertyAccessor.java:266)
	at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:104)
	at org.springframework.validation.DataBinder.applyPropertyValues(DataBinder.java:848)
	at org.springframework.validation.DataBinder.doBind(DataBinder.java:744)
	at org.springframework.web.bind.WebDataBinder.doBind(WebDataBinder.java:197)
	at org.springframework.web.bind.ServletRequestDataBinder.bind(ServletRequestDataBinder.java:107)

This works as expected when MultiValueMap<String, String> is replaced with Map<String, List<String>>

@MHajoha MHajoha changed the title Nested MultiValueMap in POJO causes ClassCastException during binding Nested MultiValueMap in POJO causes ClassCastException during binding Dec 18, 2020
@MHajoha MHajoha changed the title Nested MultiValueMap in POJO causes ClassCastException during binding Nested MultiValueMap in bean causes ClassCastException when binding request params Dec 18, 2020
@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged or decided on label Dec 18, 2020
@jhoeller jhoeller self-assigned this Dec 18, 2020
@jhoeller jhoeller added in: core Issues in core modules (aop, beans, core, context, expression) type: bug A general bug and removed status: waiting-for-triage An issue we've not yet triaged or decided on labels Dec 20, 2020
@jhoeller jhoeller added this to the 5.3.3 milestone Dec 20, 2020
@jhoeller
Copy link
Contributor

MultiValueMap value type detection does not seem to work in the core BeanWrapper infrastructure underneath such a web data binding attempt, whereas it does work for a generically typed Map with explicit collection values. We'll revisit this for 5.3.3, with an intent for a 5.2.13 backport.

@jhoeller jhoeller added the in: web Issues in web modules (web, webmvc, webflux, websocket) label Dec 20, 2020
@jhoeller jhoeller modified the milestones: 5.3.3, 5.3.4 Jan 11, 2021
@jhoeller jhoeller changed the title Nested MultiValueMap in bean causes ClassCastException when binding request params Support for MultiValueMap elements in web data binding Jan 22, 2021
@jhoeller jhoeller added type: enhancement A general enhancement and removed type: bug A general bug labels Jan 22, 2021
@jhoeller
Copy link
Contributor

This turns out to be rather involved and simply not covered by our general Map support in the core BeanWrapper infrastructure. We can certainly support MultiValueMap specifically in separate code paths but this is only likely to materialize in 5.3.x at this point.

@jhoeller jhoeller modified the milestones: 5.3.4, 5.3.5 Feb 7, 2021
@jhoeller jhoeller modified the milestones: 5.3.5, 5.3.6 Mar 11, 2021
@jhoeller jhoeller modified the milestones: 5.3.6, 5.3.7 Apr 12, 2021
@jhoeller jhoeller modified the milestones: 5.3.7, 5.3.8 May 10, 2021
@jhoeller jhoeller modified the milestones: 5.3.8, 5.3.9 Jun 4, 2021
@jhoeller jhoeller modified the milestones: 5.3.9, 5.3.10 Jul 7, 2021
@jhoeller jhoeller modified the milestones: 5.3.10, 5.x Backlog Sep 13, 2021
@jhoeller jhoeller modified the milestones: 6.x Backlog, 6.1.0-M2 Jul 12, 2023
@jhoeller
Copy link
Contributor

Finally coming into 6.1 through a revised PropertyHandler arrangement where we resolve map value types as a TypeDescriptor now, introspecting the actual Map generics and not the top-level generics on MultiValueMap.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: core Issues in core modules (aop, beans, core, context, expression) in: web Issues in web modules (web, webmvc, webflux, websocket) type: enhancement A general enhancement
Projects
None yet
Development

No branches or pull requests

3 participants