Set up Spring @RequestParam Deserialization for maps and / or nested objects

@RestController class MyController { @RequestMapping(...) public void test(Container container) { ... } } 

Spring by default uses Dot-Notation to deserialize the nested @RequestParam:

 class Container { A a; } class A { String val; } 

work with:

 http://.../myController?a.val=foo 

But for cards, it uses a square bracket designation:

 class Container { Map<String, String> a; } 

work with:

 http://.../myController?a[val]=foo 

When using JavaScript there, of course, there is no difference between the HashMap and the embedded object, so everything will be serialized either with the squares of the square Dots brackets , or


Question:

How / where can I tell Spring (or Spring Boot, if it's easier) to use Dot-Notation (or square brackets) for both , nested objects and Maps?

Or is there a reason Spring makes a difference between these types?

+6
source share
1 answer

Spring Boot supports the use of point-separated paths for map bindings thanks to its DataBinder subclass, RelaxedDataBinder . The good news is that it is also a DataBinder , which was used in Spring MVC to bind query parameters. The bad news is that connecting your own binder is not easy and that it should be WebDataBinder . You can connect it by declaring your own RequestMappingHandlerAdapter bean named RequestMappingHandlerAdapter . For instance:

 @Bean public RequestMappingHandlerAdapter requestMappingHandlerAdpter() { return new RequestMappingHandlerAdapter() { @Override protected InitBinderDataBinderFactory createDataBinderFactory( List<InvocableHandlerMethod> binderMethods) throws Exception { return new ServletRequestDataBinderFactory(binderMethods, getWebBindingInitializer()) { @Override protected ServletRequestDataBinder createBinderInstance( final Object target, String objectName, NativeWebRequest request) { return new ServletRequestDataBinder(target) { private RelaxedDataBinder relaxedBinder = new RelaxedDataBinder(target); @Override protected void doBind(MutablePropertyValues mpvs) { this.relaxedBinder.bind(mpvs); } }; } }; } }; } 

You may want to reorganize this to avoid using multiple nested anonymous inner classes, but hopefully illustrates the general approach.

+4
source

Source: https://habr.com/ru/post/982057/


All Articles