为地图和/或嵌套对象自定义Spring @RequestParam反序列化

时间:2015-02-05 16:46:56

标签: spring spring-mvc spring-boot spring-4 http-request-parameters

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

默认情况下,Spring使用Dot-Notation反序列化嵌套的@RequestParam:

class Container {
    A a;
}

class A {
    String val;
}

适用于:

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

但对于地图,它使用方形括号表示法:

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

适用于:

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

当使用JavaScript时,HashMap和嵌套对象之间当然没有区别,因此所有内容都将使用Dots Square-Brackets进行序列化。


问题:

如何/在哪里可以告诉Spring(或者Spring Boot,如果更容易)使用Dot-Notation(或Square Brackets)来两者,嵌套对象地图?

或者,为什么Spring会在这些类型之间产生影响?

2 个答案:

答案 0 :(得分:4)

Spring Boot支持使用点分隔路径来绑定地图,这要归功于其自定义DataBinder子类RelaxedDataBinder。好消息是它也是一个DataBinder,它在Spring MVC中用于执行请求参数绑定。坏消息是插入自己的活页夹并不简单,而且需要WebDataBinder。您可以通过声明自己的名为RequestMappingHandlerAdapter的{​​{1}} bean来插入一个。例如:

requestMappingHandlerAdapter

您可能希望重构此操作以避免使用多个嵌套的匿名内部类,但它有望说明一般方法。

答案 1 :(得分:0)

content = content.replace(/(.+)\r?\n=+$/gm, '<div>$1</div>');
content = content.replace(/(.+)\r?\n-+$/gm, '<p>$1</p>');

这就是我摆脱它的方式;控制器中委派给@InitBinder private void initBinder(WebDataBinder binder, ServletRequest request) { new RelaxedDataBinder(binder.getTarget()).bind(new ServletRequestParameterPropertyValues(request)); } 的方法。