POLISH CREATION OF DATA BINDERS FOR @RequestMapping METHODS
Make it possible to hook in custom ServletRequestDataBinderFactory by overriding RequestMappingHandlerAdapter. Create ExtendedServletRequestDataBinder to add URI template vars to the binding values taking advantage of a new extension hook in ServletRequestDataBinder to provide additional values to bind.
This commit is contained in:
@@ -108,9 +108,20 @@ public class ServletRequestDataBinder extends WebDataBinder {
|
||||
if (multipartRequest != null) {
|
||||
bindMultipart(multipartRequest.getMultiFileMap(), mpvs);
|
||||
}
|
||||
addBindValues(mpvs, request);
|
||||
doBind(mpvs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extension point that subclasses can use to add extra bind values for a
|
||||
* request. Invoked before {@link #doBind(MutablePropertyValues)}.
|
||||
* The default implementation is empty.
|
||||
* @param mpvs the property values that will be used for data binding
|
||||
* @param request the current request
|
||||
*/
|
||||
protected void addBindValues(MutablePropertyValues mpvs, ServletRequest request) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Treats errors as fatal.
|
||||
* <p>Use this method only if it's an error if the input isn't valid.
|
||||
|
||||
@@ -41,10 +41,12 @@ public class DefaultDataBinderFactory implements WebDataBinderFactory {
|
||||
/**
|
||||
* Create a new {@link WebDataBinder} for the given target object and
|
||||
* initialize it through a {@link WebBindingInitializer}.
|
||||
* @throws Exception in case of invalid state or arguments
|
||||
*/
|
||||
public final WebDataBinder createBinder(NativeWebRequest webRequest, Object target, String objectName) throws Exception {
|
||||
public final WebDataBinder createBinder(NativeWebRequest webRequest, Object target, String objectName)
|
||||
throws Exception {
|
||||
WebDataBinder dataBinder = createBinderInstance(target, objectName, webRequest);
|
||||
if (initializer != null) {
|
||||
if (this.initializer != null) {
|
||||
this.initializer.initBinder(dataBinder, webRequest);
|
||||
}
|
||||
initBinder(dataBinder, webRequest);
|
||||
@@ -52,13 +54,15 @@ public class DefaultDataBinderFactory implements WebDataBinderFactory {
|
||||
}
|
||||
|
||||
/**
|
||||
* Extension point to create the WebDataBinder instance, which is
|
||||
* {@link WebRequestDataBinder} by default.
|
||||
* Extension point to create the WebDataBinder instance.
|
||||
* By default this is {@code WebRequestDataBinder}.
|
||||
* @param target the binding target or {@code null} for type conversion only
|
||||
* @param objectName the binding target object name
|
||||
* @param webRequest the current request
|
||||
* @throws Exception in case of invalid state or arguments
|
||||
*/
|
||||
protected WebDataBinder createBinderInstance(Object target, String objectName, NativeWebRequest webRequest) {
|
||||
protected WebDataBinder createBinderInstance(Object target, String objectName, NativeWebRequest webRequest)
|
||||
throws Exception {
|
||||
return new WebRequestDataBinder(target, objectName);
|
||||
}
|
||||
|
||||
|
||||
@@ -58,12 +58,11 @@ public class InitBinderDataBinderFactory extends DefaultDataBinderFactory {
|
||||
@Override
|
||||
public void initBinder(WebDataBinder binder, NativeWebRequest request) throws Exception {
|
||||
for (InvocableHandlerMethod binderMethod : this.binderMethods) {
|
||||
if (!invokeInitBinderMethod(binderMethod, binder)) {
|
||||
continue;
|
||||
}
|
||||
Object returnValue = binderMethod.invokeForRequest(request, null, binder);
|
||||
if (returnValue != null) {
|
||||
throw new IllegalStateException("@InitBinder methods should return void: " + binderMethod);
|
||||
if (isBinderMethodApplicable(binderMethod, binder)) {
|
||||
Object returnValue = binderMethod.invokeForRequest(request, null, binder);
|
||||
if (returnValue != null) {
|
||||
throw new IllegalStateException("@InitBinder methods should return void: " + binderMethod);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -74,8 +73,8 @@ public class InitBinderDataBinderFactory extends DefaultDataBinderFactory {
|
||||
* <p>The default implementation checks if target object name is included
|
||||
* in the attribute names specified in the {@code @InitBinder} annotation.
|
||||
*/
|
||||
protected boolean invokeInitBinderMethod(HandlerMethod binderMethod, WebDataBinder binder) {
|
||||
InitBinder annot = binderMethod.getMethodAnnotation(InitBinder.class);
|
||||
protected boolean isBinderMethodApplicable(HandlerMethod initBinderMethod, WebDataBinder binder) {
|
||||
InitBinder annot = initBinderMethod.getMethodAnnotation(InitBinder.class);
|
||||
Collection<String> names = Arrays.asList(annot.value());
|
||||
return (names.size() == 0 || names.contains(binder.getObjectName()));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user