提交 2092a31f 编写于 作者: C Chris Beams

Rename DataBinderFactory subtypes for concision

上级 446dfdbf
...@@ -59,7 +59,6 @@ import org.springframework.web.bind.support.WebDataBinderFactory; ...@@ -59,7 +59,6 @@ import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.ServletWebRequest; import org.springframework.web.context.request.ServletWebRequest;
import org.springframework.web.method.HandlerMethod; import org.springframework.web.method.HandlerMethod;
import org.springframework.web.method.HandlerMethodSelector; import org.springframework.web.method.HandlerMethodSelector;
import org.springframework.web.method.annotation.InitBinderMethodDataBinderFactory;
import org.springframework.web.method.annotation.ModelFactory; import org.springframework.web.method.annotation.ModelFactory;
import org.springframework.web.method.annotation.SessionAttributesHandler; import org.springframework.web.method.annotation.SessionAttributesHandler;
import org.springframework.web.method.annotation.support.ErrorsMethodArgumentResolver; import org.springframework.web.method.annotation.support.ErrorsMethodArgumentResolver;
...@@ -95,23 +94,23 @@ import org.springframework.web.util.WebUtils; ...@@ -95,23 +94,23 @@ import org.springframework.web.util.WebUtils;
/** /**
* An {@link AbstractHandlerMethodAdapter} variant with support for {@link RequestMapping} handler methods. * An {@link AbstractHandlerMethodAdapter} variant with support for {@link RequestMapping} handler methods.
* *
* <p>Processing a {@link RequestMapping} method typically involves the invocation of {@link ModelAttribute} * <p>Processing a {@link RequestMapping} method typically involves the invocation of {@link ModelAttribute}
* methods for contributing attributes to the model and {@link InitBinder} methods for initializing * methods for contributing attributes to the model and {@link InitBinder} methods for initializing
* {@link WebDataBinder} instances for data binding and type conversion purposes. * {@link WebDataBinder} instances for data binding and type conversion purposes.
* *
* <p>{@link InvocableHandlerMethod} is the key contributor that helps with the invocation of handler * <p>{@link InvocableHandlerMethod} is the key contributor that helps with the invocation of handler
* methods of all types resolving their arguments through registered {@link HandlerMethodArgumentResolver}s. * methods of all types resolving their arguments through registered {@link HandlerMethodArgumentResolver}s.
* {@link ServletInvocableHandlerMethod} on the other hand adds handling of the return value for {@link RequestMapping} * {@link ServletInvocableHandlerMethod} on the other hand adds handling of the return value for {@link RequestMapping}
* methods through registered {@link HandlerMethodReturnValueHandler}s resulting in a {@link ModelAndView}. * methods through registered {@link HandlerMethodReturnValueHandler}s resulting in a {@link ModelAndView}.
* *
* <p>{@link ModelFactory} is another contributor that assists with the invocation of all {@link ModelAttribute} * <p>{@link ModelFactory} is another contributor that assists with the invocation of all {@link ModelAttribute}
* methods to populate a model while {@link InitBinderMethodDataBinderFactory} assists with the invocation of * methods to populate a model while {@link ServletRequestDataBinderFactory} assists with the invocation of
* {@link InitBinder} methods for initializing data binder instances when needed. * {@link InitBinder} methods for initializing data binder instances when needed.
* *
* <p>This class is the central point that assembles all of mentioned contributors and invokes the actual * <p>This class is the central point that assembles all of mentioned contributors and invokes the actual
* {@link RequestMapping} handler method through a {@link ServletInvocableHandlerMethod}. * {@link RequestMapping} handler method through a {@link ServletInvocableHandlerMethod}.
* *
* @author Rossen Stoyanchev * @author Rossen Stoyanchev
* @since 3.1 * @since 3.1
* @see InvocableHandlerMethod * @see InvocableHandlerMethod
...@@ -172,18 +171,18 @@ public class RequestMappingHandlerMethodAdapter extends AbstractHandlerMethodAda ...@@ -172,18 +171,18 @@ public class RequestMappingHandlerMethodAdapter extends AbstractHandlerMethodAda
/** /**
* Set one or more custom argument resolvers to use with {@link RequestMapping}, {@link ModelAttribute}, and * Set one or more custom argument resolvers to use with {@link RequestMapping}, {@link ModelAttribute}, and
* {@link InitBinder} methods. Custom argument resolvers are given a chance to resolve argument values * {@link InitBinder} methods. Custom argument resolvers are given a chance to resolve argument values
* ahead of the standard argument resolvers registered by default. * ahead of the standard argument resolvers registered by default.
* <p>An existing {@link WebArgumentResolver} can either adapted with {@link ServletWebArgumentResolverAdapter} * <p>An existing {@link WebArgumentResolver} can either adapted with {@link ServletWebArgumentResolverAdapter}
* or preferably converted to a {@link HandlerMethodArgumentResolver} instead. * or preferably converted to a {@link HandlerMethodArgumentResolver} instead.
*/ */
public void setCustomArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) { public void setCustomArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
this.customArgumentResolvers = argumentResolvers; this.customArgumentResolvers = argumentResolvers;
} }
/** /**
* Set the argument resolvers to use with {@link RequestMapping} and {@link ModelAttribute} methods. * Set the argument resolvers to use with {@link RequestMapping} and {@link ModelAttribute} methods.
* This is an optional property providing full control over all argument resolvers in contrast to * This is an optional property providing full control over all argument resolvers in contrast to
* {@link #setCustomArgumentResolvers(List)}, which does not override default registrations. * {@link #setCustomArgumentResolvers(List)}, which does not override default registrations.
* @param argumentResolvers argument resolvers for {@link RequestMapping} and {@link ModelAttribute} methods * @param argumentResolvers argument resolvers for {@link RequestMapping} and {@link ModelAttribute} methods
*/ */
...@@ -195,8 +194,8 @@ public class RequestMappingHandlerMethodAdapter extends AbstractHandlerMethodAda ...@@ -195,8 +194,8 @@ public class RequestMappingHandlerMethodAdapter extends AbstractHandlerMethodAda
} }
/** /**
* Set the argument resolvers to use with {@link InitBinder} methods. This is an optional property * Set the argument resolvers to use with {@link InitBinder} methods. This is an optional property
* providing full control over all argument resolvers for {@link InitBinder} methods in contrast to * providing full control over all argument resolvers for {@link InitBinder} methods in contrast to
* {@link #setCustomArgumentResolvers(List)}, which does not override default registrations. * {@link #setCustomArgumentResolvers(List)}, which does not override default registrations.
* @param argumentResolvers argument resolvers for {@link InitBinder} methods * @param argumentResolvers argument resolvers for {@link InitBinder} methods
*/ */
...@@ -208,19 +207,19 @@ public class RequestMappingHandlerMethodAdapter extends AbstractHandlerMethodAda ...@@ -208,19 +207,19 @@ public class RequestMappingHandlerMethodAdapter extends AbstractHandlerMethodAda
} }
/** /**
* Set custom return value handlers to use to handle the return values of {@link RequestMapping} methods. * Set custom return value handlers to use to handle the return values of {@link RequestMapping} methods.
* Custom return value handlers are given a chance to handle a return value before the standard * Custom return value handlers are given a chance to handle a return value before the standard
* return value handlers registered by default. * return value handlers registered by default.
* @param returnValueHandlers custom return value handlers for {@link RequestMapping} methods * @param returnValueHandlers custom return value handlers for {@link RequestMapping} methods
*/ */
public void setCustomReturnValueHandlers(List<HandlerMethodReturnValueHandler> returnValueHandlers) { public void setCustomReturnValueHandlers(List<HandlerMethodReturnValueHandler> returnValueHandlers) {
this.customReturnValueHandlers = returnValueHandlers; this.customReturnValueHandlers = returnValueHandlers;
} }
/** /**
* Set the {@link HandlerMethodReturnValueHandler}s to use to use with {@link RequestMapping} methods. * Set the {@link HandlerMethodReturnValueHandler}s to use to use with {@link RequestMapping} methods.
* This is an optional property providing full control over all return value handlers in contrast to * This is an optional property providing full control over all return value handlers in contrast to
* {@link #setCustomReturnValueHandlers(List)}, which does not override default registrations. * {@link #setCustomReturnValueHandlers(List)}, which does not override default registrations.
* @param returnValueHandlers the return value handlers for {@link RequestMapping} methods * @param returnValueHandlers the return value handlers for {@link RequestMapping} methods
*/ */
public void setReturnValueHandlers(List<HandlerMethodReturnValueHandler> returnValueHandlers) { public void setReturnValueHandlers(List<HandlerMethodReturnValueHandler> returnValueHandlers) {
...@@ -232,10 +231,10 @@ public class RequestMappingHandlerMethodAdapter extends AbstractHandlerMethodAda ...@@ -232,10 +231,10 @@ public class RequestMappingHandlerMethodAdapter extends AbstractHandlerMethodAda
/** /**
* Set custom {@link ModelAndViewResolver}s to use to handle the return values of {@link RequestMapping} methods. * Set custom {@link ModelAndViewResolver}s to use to handle the return values of {@link RequestMapping} methods.
* <p>Custom {@link ModelAndViewResolver}s are provided for backward compatibility and are invoked at the very, * <p>Custom {@link ModelAndViewResolver}s are provided for backward compatibility and are invoked at the very,
* from the {@link DefaultMethodReturnValueHandler}, after all standard {@link HandlerMethodReturnValueHandler}s * from the {@link DefaultMethodReturnValueHandler}, after all standard {@link HandlerMethodReturnValueHandler}s
* have been given a chance. This is because {@link ModelAndViewResolver}s do not have a method to indicate * have been given a chance. This is because {@link ModelAndViewResolver}s do not have a method to indicate
* if they support a given return type or not. For this reason it is recommended to use * if they support a given return type or not. For this reason it is recommended to use
* {@link HandlerMethodReturnValueHandler} and {@link #setCustomReturnValueHandlers(List)} instead. * {@link HandlerMethodReturnValueHandler} and {@link #setCustomReturnValueHandlers(List)} instead.
*/ */
public void setModelAndViewResolvers(List<ModelAndViewResolver> modelAndViewResolvers) { public void setModelAndViewResolvers(List<ModelAndViewResolver> modelAndViewResolvers) {
...@@ -413,7 +412,7 @@ public class RequestMappingHandlerMethodAdapter extends AbstractHandlerMethodAda ...@@ -413,7 +412,7 @@ public class RequestMappingHandlerMethodAdapter extends AbstractHandlerMethodAda
@Override @Override
protected boolean supportsInternal(HandlerMethod handlerMethod) { protected boolean supportsInternal(HandlerMethod handlerMethod) {
return supportsMethodParameters(handlerMethod.getMethodParameters()) && return supportsMethodParameters(handlerMethod.getMethodParameters()) &&
supportsReturnType(handlerMethod.getReturnType()); supportsReturnType(handlerMethod.getReturnType());
} }
...@@ -465,8 +464,8 @@ public class RequestMappingHandlerMethodAdapter extends AbstractHandlerMethodAda ...@@ -465,8 +464,8 @@ public class RequestMappingHandlerMethodAdapter extends AbstractHandlerMethodAda
} }
/** /**
* Whether the given handler type defines any handler-specific session attributes via {@link SessionAttributes}. * Whether the given handler type defines any handler-specific session attributes via {@link SessionAttributes}.
* Also initializes the sessionAttributesHandlerCache for the given handler type. * Also initializes the sessionAttributesHandlerCache for the given handler type.
*/ */
private boolean hasSessionAttributes(Class<?> handlerType) { private boolean hasSessionAttributes(Class<?> handlerType) {
SessionAttributesHandler handler = null; SessionAttributesHandler handler = null;
...@@ -483,8 +482,8 @@ public class RequestMappingHandlerMethodAdapter extends AbstractHandlerMethodAda ...@@ -483,8 +482,8 @@ public class RequestMappingHandlerMethodAdapter extends AbstractHandlerMethodAda
/** /**
* Invoke the {@link RequestMapping} handler method preparing a {@link ModelAndView} if view resolution is required. * Invoke the {@link RequestMapping} handler method preparing a {@link ModelAndView} if view resolution is required.
*/ */
private ModelAndView invokeHandlerMethod(HttpServletRequest request, private ModelAndView invokeHandlerMethod(HttpServletRequest request,
HttpServletResponse response, HttpServletResponse response,
HandlerMethod handlerMethod) throws Exception { HandlerMethod handlerMethod) throws Exception {
WebDataBinderFactory binderFactory = createDataBinderFactory(handlerMethod); WebDataBinderFactory binderFactory = createDataBinderFactory(handlerMethod);
...@@ -510,7 +509,7 @@ public class RequestMappingHandlerMethodAdapter extends AbstractHandlerMethodAda ...@@ -510,7 +509,7 @@ public class RequestMappingHandlerMethodAdapter extends AbstractHandlerMethodAda
mav.setViewName(mavContainer.getViewName()); mav.setViewName(mavContainer.getViewName());
if (mavContainer.getView() != null) { if (mavContainer.getView() != null) {
mav.setView((View) mavContainer.getView()); mav.setView((View) mavContainer.getView());
} }
return mav; return mav;
} }
} }
...@@ -535,7 +534,7 @@ public class RequestMappingHandlerMethodAdapter extends AbstractHandlerMethodAda ...@@ -535,7 +534,7 @@ public class RequestMappingHandlerMethodAdapter extends AbstractHandlerMethodAda
initBinderMethods.add(binderMethod); initBinderMethods.add(binderMethod);
} }
return new ServletInitBinderMethodDataBinderFactory(initBinderMethods, this.webBindingInitializer); return new ServletRequestDataBinderFactory(initBinderMethods, this.webBindingInitializer);
} }
private ModelFactory createModelFactory(HandlerMethod handlerMethod, WebDataBinderFactory binderFactory) { private ModelFactory createModelFactory(HandlerMethod handlerMethod, WebDataBinderFactory binderFactory) {
...@@ -559,7 +558,7 @@ public class RequestMappingHandlerMethodAdapter extends AbstractHandlerMethodAda ...@@ -559,7 +558,7 @@ public class RequestMappingHandlerMethodAdapter extends AbstractHandlerMethodAda
return new ModelFactory(modelAttrMethods, binderFactory, sessionAttributesHandlerCache.get(handlerType)); return new ModelFactory(modelAttrMethods, binderFactory, sessionAttributesHandlerCache.get(handlerType));
} }
private ServletInvocableHandlerMethod createRequestMappingMethod(HandlerMethod handlerMethod, private ServletInvocableHandlerMethod createRequestMappingMethod(HandlerMethod handlerMethod,
WebDataBinderFactory binderFactory) { WebDataBinderFactory binderFactory) {
Method method = handlerMethod.getMethod(); Method method = handlerMethod.getMethod();
ServletInvocableHandlerMethod requestMethod = new ServletInvocableHandlerMethod(handlerMethod.getBean(), method); ServletInvocableHandlerMethod requestMethod = new ServletInvocableHandlerMethod(handlerMethod.getBean(), method);
...@@ -586,7 +585,7 @@ public class RequestMappingHandlerMethodAdapter extends AbstractHandlerMethodAda ...@@ -586,7 +585,7 @@ public class RequestMappingHandlerMethodAdapter extends AbstractHandlerMethodAda
public static MethodFilter MODEL_ATTRIBUTE_METHODS = new MethodFilter() { public static MethodFilter MODEL_ATTRIBUTE_METHODS = new MethodFilter() {
public boolean matches(Method method) { public boolean matches(Method method) {
return ((AnnotationUtils.findAnnotation(method, RequestMapping.class) == null) && return ((AnnotationUtils.findAnnotation(method, RequestMapping.class) == null) &&
(AnnotationUtils.findAnnotation(method, ModelAttribute.class) != null)); (AnnotationUtils.findAnnotation(method, ModelAttribute.class) != null));
} }
}; };
......
...@@ -23,32 +23,42 @@ import org.springframework.beans.MutablePropertyValues; ...@@ -23,32 +23,42 @@ import org.springframework.beans.MutablePropertyValues;
import org.springframework.web.bind.ServletRequestDataBinder; import org.springframework.web.bind.ServletRequestDataBinder;
import org.springframework.web.bind.WebDataBinder; import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.support.WebBindingInitializer; import org.springframework.web.bind.support.WebBindingInitializer;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.context.request.RequestAttributes; import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.method.annotation.InitBinderMethodDataBinderFactory; import org.springframework.web.method.annotation.InitBinderDataBinderFactory;
import org.springframework.web.method.support.InvocableHandlerMethod; import org.springframework.web.method.support.InvocableHandlerMethod;
import org.springframework.web.servlet.HandlerMapping; import org.springframework.web.servlet.HandlerMapping;
/** /**
* An {@link InitBinderMethodDataBinderFactory} variation instantiating a data binder of type * An {@link InitBinderDataBinderFactory} variation instantiating a data binder of type
* {@link ServletRequestDataBinder} and further extending it with the ability to add URI template variables * {@link ServletRequestDataBinder} and further extending it with the ability to add URI template variables
* to the values used in data binding. * to the values used in data binding.
* *
* @author Rossen Stoyanchev * @author Rossen Stoyanchev
* @since 3.1 * @since 3.1
*/ */
public class ServletInitBinderMethodDataBinderFactory extends InitBinderMethodDataBinderFactory { public class ServletRequestDataBinderFactory extends InitBinderDataBinderFactory {
/** /**
* Create an {@link ServletInitBinderMethodDataBinderFactory} instance. * Create an {@link ServletRequestDataBinderFactory} instance.
* @param initBinderMethods init binder methods to use to initialize new data binders. * @param initBinderMethods init binder methods to use to initialize new data binders.
* @param bindingInitializer a WebBindingInitializer to use to initialize created data binder instances. * @param bindingInitializer a WebBindingInitializer to use to initialize created data binder instances.
*/ */
public ServletInitBinderMethodDataBinderFactory(List<InvocableHandlerMethod> initBinderMethods, public ServletRequestDataBinderFactory(List<InvocableHandlerMethod> initBinderMethods,
WebBindingInitializer bindingInitializer) { WebBindingInitializer bindingInitializer) {
super(initBinderMethods, bindingInitializer); super(initBinderMethods, bindingInitializer);
} }
/**
* Returns the more specific {@link ServletRequestDataBinder} created by {@link #createBinderInstance(Object, String)}.
*/
@Override
public ServletRequestDataBinder createBinder(NativeWebRequest request, Object target, String objectName)
throws Exception {
return (ServletRequestDataBinder) super.createBinder(request, target, objectName);
}
/** /**
* {@inheritDoc} * {@inheritDoc}
* <p>This method creates a {@link ServletRequestDataBinder} instance that also adds URI template variables to * <p>This method creates a {@link ServletRequestDataBinder} instance that also adds URI template variables to
...@@ -90,4 +100,4 @@ public class ServletInitBinderMethodDataBinderFactory extends InitBinderMethodDa ...@@ -90,4 +100,4 @@ public class ServletInitBinderMethodDataBinderFactory extends InitBinderMethodDa
} }
} }
} }
\ No newline at end of file
...@@ -34,13 +34,13 @@ import org.springframework.web.context.request.ServletWebRequest; ...@@ -34,13 +34,13 @@ import org.springframework.web.context.request.ServletWebRequest;
import org.springframework.web.servlet.HandlerMapping; import org.springframework.web.servlet.HandlerMapping;
/** /**
* Test fixture with {@link ServletInitBinderMethodDataBinderFactory}. * Test fixture with {@link ServletRequestDataBinderFactory}.
* *
* @author Rossen Stoyanchev * @author Rossen Stoyanchev
*/ */
public class ServletInitBinderMethodDataBinderFactoryTests { public class ServletRequestDataBinderFactoryTests {
private ServletInitBinderMethodDataBinderFactory binderFactory; private ServletRequestDataBinderFactory binderFactory;
private MockHttpServletRequest request; private MockHttpServletRequest request;
...@@ -48,7 +48,7 @@ public class ServletInitBinderMethodDataBinderFactoryTests { ...@@ -48,7 +48,7 @@ public class ServletInitBinderMethodDataBinderFactoryTests {
@Before @Before
public void setup() { public void setup() {
binderFactory = new ServletInitBinderMethodDataBinderFactory(null, null); binderFactory = new ServletRequestDataBinderFactory(null, null);
request = new MockHttpServletRequest(); request = new MockHttpServletRequest();
webRequest = new ServletWebRequest(request); webRequest = new ServletWebRequest(request);
RequestContextHolder.setRequestAttributes(webRequest); RequestContextHolder.setRequestAttributes(webRequest);
......
...@@ -30,32 +30,32 @@ import org.springframework.web.context.request.NativeWebRequest; ...@@ -30,32 +30,32 @@ import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.InvocableHandlerMethod; import org.springframework.web.method.support.InvocableHandlerMethod;
/** /**
* A specialization of {@link DefaultDataBinderFactory} that further initializes {@link WebDataBinder} instances * A specialization of {@link DefaultDataBinderFactory} that further initializes {@link WebDataBinder} instances
* by invoking {@link InitBinder} methods. * by invoking {@link InitBinder} methods.
* *
* @author Rossen Stoyanchev * @author Rossen Stoyanchev
* @since 3.1 * @since 3.1
*/ */
public class InitBinderMethodDataBinderFactory extends DefaultDataBinderFactory { public class InitBinderDataBinderFactory extends DefaultDataBinderFactory {
private final List<InvocableHandlerMethod> initBinderMethods; private final List<InvocableHandlerMethod> initBinderMethods;
/** /**
* Create an {@code InitBinderMethodDataBinderFactory} instance with the given {@link InitBinder} methods. * Create an {@code InitBinderDataBinderFactory} instance with the given {@link InitBinder} methods.
* @param binderMethods {@link InitBinder} methods to use to invoke to initialize new data binder instances * @param binderMethods {@link InitBinder} methods to use to invoke to initialize new data binder instances
* @param bindingInitializer a {@link WebBindingInitializer} to initialize new data binder instances with * @param bindingInitializer a {@link WebBindingInitializer} to initialize new data binder instances with
*/ */
public InitBinderMethodDataBinderFactory(List<InvocableHandlerMethod> binderMethods, public InitBinderDataBinderFactory(List<InvocableHandlerMethod> binderMethods,
WebBindingInitializer bindingInitializer) { WebBindingInitializer bindingInitializer) {
super(bindingInitializer); super(bindingInitializer);
this.initBinderMethods = (binderMethods != null) ? binderMethods : new ArrayList<InvocableHandlerMethod>(); this.initBinderMethods = (binderMethods != null) ? binderMethods : new ArrayList<InvocableHandlerMethod>();
} }
/** /**
* Create a {@link WebDataBinder} for the given object and initialize it by calling {@link InitBinder} methods. * Create a {@link WebDataBinder} for the given object and initialize it by calling {@link InitBinder} methods.
* Only methods with an {@link InitBinder} annotation value that doesn't list attributes names or methods with * Only methods with an {@link InitBinder} annotation value that doesn't list attributes names or methods with
* an {@link InitBinder} annotation value that matches the target object name are invoked. * an {@link InitBinder} annotation value that matches the target object name are invoked.
* @see InitBinder#value() * @see InitBinder#value()
*/ */
@Override @Override
public WebDataBinder createBinder(NativeWebRequest request, Object target, String objectName) throws Exception { public WebDataBinder createBinder(NativeWebRequest request, Object target, String objectName) throws Exception {
......
...@@ -35,16 +35,16 @@ import org.springframework.web.method.support.HandlerMethodReturnValueHandler; ...@@ -35,16 +35,16 @@ import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
import org.springframework.web.method.support.ModelAndViewContainer; import org.springframework.web.method.support.ModelAndViewContainer;
/** /**
* Resolves method arguments annotated with @{@link ModelAttribute}. Or if created in default resolution mode, * Resolves method arguments annotated with @{@link ModelAttribute}. Or if created in default resolution mode,
* resolves any non-simple type argument even without an @{@link ModelAttribute}. See the constructor for details. * resolves any non-simple type argument even without an @{@link ModelAttribute}. See the constructor for details.
* *
* <p>A model attribute argument value is obtained from the model or is created using its default constructor. * <p>A model attribute argument value is obtained from the model or is created using its default constructor.
* Data binding and optionally validation is then applied through a {@link WebDataBinder} instance. Validation is * Data binding and optionally validation is then applied through a {@link WebDataBinder} instance. Validation is
* invoked optionally when the argument is annotated with an {@code @Valid}. * invoked optionally when the argument is annotated with an {@code @Valid}.
* *
* <p>Also handles return values from methods annotated with an @{@link ModelAttribute}. The return value is * <p>Also handles return values from methods annotated with an @{@link ModelAttribute}. The return value is
* added to the {@link ModelAndViewContainer}. * added to the {@link ModelAndViewContainer}.
* *
* @author Rossen Stoyanchev * @author Rossen Stoyanchev
* @since 3.1 * @since 3.1
*/ */
...@@ -54,7 +54,7 @@ public class ModelAttributeMethodProcessor implements HandlerMethodArgumentResol ...@@ -54,7 +54,7 @@ public class ModelAttributeMethodProcessor implements HandlerMethodArgumentResol
/** /**
* @param useDefaultResolution in default resolution mode a method argument that isn't a simple type, as * @param useDefaultResolution in default resolution mode a method argument that isn't a simple type, as
* defined in {@link BeanUtils#isSimpleProperty(Class)}, is treated as a model attribute even if it doesn't * defined in {@link BeanUtils#isSimpleProperty(Class)}, is treated as a model attribute even if it doesn't
* have an @{@link ModelAttribute} annotation with its name derived from the model attribute type. * have an @{@link ModelAttribute} annotation with its name derived from the model attribute type.
*/ */
public ModelAttributeMethodProcessor(boolean useDefaultResolution) { public ModelAttributeMethodProcessor(boolean useDefaultResolution) {
...@@ -62,8 +62,8 @@ public class ModelAttributeMethodProcessor implements HandlerMethodArgumentResol ...@@ -62,8 +62,8 @@ public class ModelAttributeMethodProcessor implements HandlerMethodArgumentResol
} }
/** /**
* @return true if the parameter is annotated with {@link ModelAttribute} or if it is a * @return true if the parameter is annotated with {@link ModelAttribute} or if it is a
* simple type without any annotations. * simple type without any annotations.
*/ */
public boolean supportsParameter(MethodParameter parameter) { public boolean supportsParameter(MethodParameter parameter) {
if (parameter.hasParameterAnnotation(ModelAttribute.class)) { if (parameter.hasParameterAnnotation(ModelAttribute.class)) {
...@@ -79,14 +79,14 @@ public class ModelAttributeMethodProcessor implements HandlerMethodArgumentResol ...@@ -79,14 +79,14 @@ public class ModelAttributeMethodProcessor implements HandlerMethodArgumentResol
/** /**
* Resolves the argument to a model attribute looking up the attribute in the model or instantiating it using its * Resolves the argument to a model attribute looking up the attribute in the model or instantiating it using its
* default constructor. Data binding and optionally validation is then applied through a {@link WebDataBinder} * default constructor. Data binding and optionally validation is then applied through a {@link WebDataBinder}
* instance. Validation is invoked optionally when the method parameter is annotated with an {@code @Valid}. * instance. Validation is invoked optionally when the method parameter is annotated with an {@code @Valid}.
* *
* @throws Exception if a {@link WebDataBinder} could not be created or if data binding and validation result in * @throws Exception if a {@link WebDataBinder} could not be created or if data binding and validation result in
* an error and the next method parameter is not of type {@link Errors} or {@link BindingResult}. * an error and the next method parameter is not of type {@link Errors} or {@link BindingResult}.
*/ */
public final Object resolveArgument(MethodParameter parameter, public final Object resolveArgument(MethodParameter parameter,
ModelAndViewContainer mavContainer, ModelAndViewContainer mavContainer,
NativeWebRequest webRequest, NativeWebRequest webRequest,
WebDataBinderFactory binderFactory) throws Exception { WebDataBinderFactory binderFactory) throws Exception {
WebDataBinder binder = createDataBinder(parameter, mavContainer, webRequest, binderFactory); WebDataBinder binder = createDataBinder(parameter, mavContainer, webRequest, binderFactory);
...@@ -111,9 +111,9 @@ public class ModelAttributeMethodProcessor implements HandlerMethodArgumentResol ...@@ -111,9 +111,9 @@ public class ModelAttributeMethodProcessor implements HandlerMethodArgumentResol
/** /**
* Creates a {@link WebDataBinder} for a target object. * Creates a {@link WebDataBinder} for a target object.
*/ */
private WebDataBinder createDataBinder(MethodParameter parameter, private WebDataBinder createDataBinder(MethodParameter parameter,
ModelAndViewContainer mavContainer, ModelAndViewContainer mavContainer,
NativeWebRequest webRequest, NativeWebRequest webRequest,
WebDataBinderFactory binderFactory) throws Exception { WebDataBinderFactory binderFactory) throws Exception {
String attrName = ModelFactory.getNameForParameter(parameter); String attrName = ModelFactory.getNameForParameter(parameter);
...@@ -128,13 +128,19 @@ public class ModelAttributeMethodProcessor implements HandlerMethodArgumentResol ...@@ -128,13 +128,19 @@ public class ModelAttributeMethodProcessor implements HandlerMethodArgumentResol
return binderFactory.createBinder(webRequest, target, attrName); return binderFactory.createBinder(webRequest, target, attrName);
} }
/**
* Bind the request to the target object contained in the provided binder instance.
*
* @param binder the binder with the target object to apply request values to
* @param request the current request
*/
protected void doBind(WebDataBinder binder, NativeWebRequest request) { protected void doBind(WebDataBinder binder, NativeWebRequest request) {
((WebRequestDataBinder) binder).bind(request); ((WebRequestDataBinder) binder).bind(request);
} }
/** /**
* Whether to validate the target object of the given {@link WebDataBinder} instance. * Whether to validate the target object of the given {@link WebDataBinder} instance.
* @param binder the data binder containing the validation candidate * @param binder the data binder containing the validation candidate
* @param parameter the method argument for which data binding is performed * @param parameter the method argument for which data binding is performed
* @return true if {@link DataBinder#validate()} should be invoked, false otherwise. * @return true if {@link DataBinder#validate()} should be invoked, false otherwise.
*/ */
...@@ -150,7 +156,7 @@ public class ModelAttributeMethodProcessor implements HandlerMethodArgumentResol ...@@ -150,7 +156,7 @@ public class ModelAttributeMethodProcessor implements HandlerMethodArgumentResol
/** /**
* Whether to raise a {@link BindException} in case of data binding or validation errors. * Whether to raise a {@link BindException} in case of data binding or validation errors.
* @param binder the binder on which validation is to be invoked * @param binder the binder on which validation is to be invoked
* @param parameter the method argument for which data binding is performed * @param parameter the method argument for which data binding is performed
* @return true if the binding or validation errors should result in a {@link BindException}, false otherwise. * @return true if the binding or validation errors should result in a {@link BindException}, false otherwise.
*/ */
...@@ -166,8 +172,8 @@ public class ModelAttributeMethodProcessor implements HandlerMethodArgumentResol ...@@ -166,8 +172,8 @@ public class ModelAttributeMethodProcessor implements HandlerMethodArgumentResol
return returnType.getMethodAnnotation(ModelAttribute.class) != null; return returnType.getMethodAnnotation(ModelAttribute.class) != null;
} }
public void handleReturnValue(Object returnValue, public void handleReturnValue(Object returnValue,
MethodParameter returnType, MethodParameter returnType,
ModelAndViewContainer mavContainer, ModelAndViewContainer mavContainer,
NativeWebRequest webRequest) throws Exception { NativeWebRequest webRequest) throws Exception {
if (returnValue != null) { if (returnValue != null) {
......
...@@ -43,11 +43,11 @@ import org.springframework.web.method.support.InvocableHandlerMethod; ...@@ -43,11 +43,11 @@ import org.springframework.web.method.support.InvocableHandlerMethod;
import org.springframework.web.method.support.HandlerMethodArgumentResolverComposite; import org.springframework.web.method.support.HandlerMethodArgumentResolverComposite;
/** /**
* Test fixture with {@link InitBinderMethodDataBinderFactory}. * Test fixture with {@link InitBinderDataBinderFactory}.
* *
* @author Rossen Stoyanchev * @author Rossen Stoyanchev
*/ */
public class InitBinderMethodDataBinderFactoryTests { public class InitBinderDataBinderFactoryTests {
private ConfigurableWebBindingInitializer bindingInitializer; private ConfigurableWebBindingInitializer bindingInitializer;
...@@ -128,7 +128,7 @@ public class InitBinderMethodDataBinderFactoryTests { ...@@ -128,7 +128,7 @@ public class InitBinderMethodDataBinderFactoryTests {
handlerMethod.setDataBinderFactory(new DefaultDataBinderFactory(null)); handlerMethod.setDataBinderFactory(new DefaultDataBinderFactory(null));
handlerMethod.setParameterNameDiscoverer(new LocalVariableTableParameterNameDiscoverer()); handlerMethod.setParameterNameDiscoverer(new LocalVariableTableParameterNameDiscoverer());
return new InitBinderMethodDataBinderFactory(Arrays.asList(handlerMethod), bindingInitializer); return new InitBinderDataBinderFactory(Arrays.asList(handlerMethod), bindingInitializer);
} }
private static class InitBinderHandler { private static class InitBinderHandler {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册