8
@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 和嵌套对象之间当然没有区别,因此所有内容都将使用点方括号进行序列化。


问题:

我如何/在哪里可以告诉 Spring(或 Spring Boot,如果这更容易的话)对嵌套对象和 Maps 使用点表示法(或括号

或者有什么理由让 Spring 在这些类型之间产生差异?

4

2 回答 2

5

由于其自定义DataBinder子类RelaxedDataBinder ,Spring Boot 支持使用点分隔路径来绑定地图。好消息是它也是DataBinderSpring MVC 中用于执行请求参数绑定的一个。坏消息是插入你自己的活页夹并不简单,它需要是一个WebDataBinder. 您可以通过声明自己的RequestMappingHandlerAdapterbean 来插入一个名为requestMappingHandlerAdapter. 例如:

@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);
                        }
                    };
                }
            };
        }   
    };
}

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

于 2015-02-10T15:21:41.830 回答
1
@InitBinder
private void initBinder(WebDataBinder binder, ServletRequest request) {
    new RelaxedDataBinder(binder.getTarget()).bind(new ServletRequestParameterPropertyValues(request));
}

我就是这样侥幸逃脱的;控制器中委托给 a 的方法RelaxedDataBinder

于 2018-11-28T19:24:28.940 回答