您可以尝试创建ServletRequestDataBinder的自定义子类,它将以下划线开头的请求参数映射到没有下划线的字段。然后您必须创建一个自定义的ServletRequestDataBinderFactory来创建一个子类。接下来,您需要创建RequestMappingHandlerAdapter的自定义子类并将其注册到 Spring MVC。这将允许您继续在 HTML 中使用下划线,而不必在 POJO 字段名称中使用下划线。
自定义 ServletRequestDataBinder:
public class MyCustomServletRequestDataBinder extends
ExtendedServletRequestDataBinder {
public MyCustomServletRequestDataBinder(Object target) {
super(target);
}
public MyCustomServletRequestDataBinder(Object target, String objectName) {
super(target, objectName);
}
@Override
protected void addBindValues(MutablePropertyValues mpvs,
ServletRequest request) {
super.addBindValues(mpvs, request);
addUnderscoreBindValues(mpvs, request);
}
protected void addUnderscoreBindValues(MutablePropertyValues mpvs,
ServletRequest request) {
// go through each parameter and check if it starts with an underscore (_)
// if it starts with an underscore, add it to mpvs under the name without
// the underscore
@SuppressWarnings("unchecked")
Map<String, Object> parameterMap = request.getParameterMap();
for (Map.Entry<String, Object> entry : parameterMap.entrySet()) {
if (StringUtils.startsWith(entry.getKey(), "_")) {
mpvs.add(StringUtils.removeStart(entry.getKey(), "_"), entry.getValue());
}
}
}
}
自定义 ServletRequestDataBinderFactory:
public class MyCustomServletRequestDataBinderFactory extends
ServletRequestDataBinderFactory {
/**
* Create a new instance.
* @param binderMethods one or more {@code @InitBinder} methods
* @param initializer provides global data binder initialization
*/
public MyCustomServletRequestDataBinderFactory(
List<InvocableHandlerMethod> binderMethods,
WebBindingInitializer initializer) {
super(binderMethods, initializer);
}
/**
* Returns an instance of {@link MyCustomServletRequestDataBinder}.
*/
@Override
protected ServletRequestDataBinder createBinderInstance(Object target,
String objectName, NativeWebRequest request) {
return new MyCustomServletRequestDataBinder(target, objectName);
}
}
自定义 RequestMappingHandlerAdapter:
public class MyCustomRequestMappingHandlerAdapter extends
RequestMappingHandlerAdapter {
public MyCustomRequestMappingHandlerAdapter() {
super();
}
/**
* {@inheritDoc} Creates an instance of
* {@link MyCustomServletRequestDataBinderFactory}.
*/
@Override
protected ServletRequestDataBinderFactory createDataBinderFactory(
List<InvocableHandlerMethod> binderMethods) throws Exception {
return new MyCustomServletRequestDataBinderFactory(binderMethods,
getWebBindingInitializer());
}
}
然后注册自定义的HandlerAdapter:
@Configuration
@Import(ValidationConfiguration.class)
@ComponentScan(basePackageClasses = ControllerScanMarker.class)
public class MyCustomHandlerConfig extends WebMvcConfigurationSupport {
/**
* {@inheritDoc} Returns the subclass
* {@link MyCustomRequestMappingHandlerAdapter} in place of the default
* {@link RequestMappingHandlerAdapter}.
*/
@Override
@Bean
public RequestMappingHandlerAdapter requestMappingHandlerAdapter() {
...
RequestMappingHandlerAdapter adapter = new MyCustomRequestMappingHandlerAdapter();
// set additional adapter fields here...
...
return adapter;
}
}
我很确定在默认请求参数绑定期间可能有一种更简单的方法来修改/添加其他值,但我不记得另一个钩子在哪里。