Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
普通程序员一名
spring-framework
提交
6fe0ff9e
S
spring-framework
项目概览
普通程序员一名
/
spring-framework
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
S
spring-framework
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
6fe0ff9e
编写于
4月 07, 2011
作者:
R
Rossen Stoyanchev
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
ModelAndViewContainer related refinements
上级
3d8b476f
变更
47
展开全部
隐藏空白更改
内联
并排
Showing
47 changed file
with
547 addition
and
1073 deletion
+547
-1073
org.springframework.web.servlet/.settings/org.eclipse.jdt.core.prefs
...ramework.web.servlet/.settings/org.eclipse.jdt.core.prefs
+1
-257
org.springframework.web.servlet/.settings/org.eclipse.jdt.ui.prefs
...gframework.web.servlet/.settings/org.eclipse.jdt.ui.prefs
+1
-2
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerMethodAdapter.java
...method/annotation/RequestMappingHandlerMethodAdapter.java
+20
-8
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerMethodExceptionResolver.java
...otation/RequestMappingHandlerMethodExceptionResolver.java
+37
-36
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ServletInitBinderMethodDataBinderFactory.java
.../annotation/ServletInitBinderMethodDataBinderFactory.java
+1
-1
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ServletInvocableHandlerMethod.java
.../mvc/method/annotation/ServletInvocableHandlerMethod.java
+50
-52
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/annotation/support/DefaultMethodReturnValueHandler.java
...d/annotation/support/DefaultMethodReturnValueHandler.java
+2
-2
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/annotation/support/HttpEntityMethodProcessor.java
.../method/annotation/support/HttpEntityMethodProcessor.java
+8
-3
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/annotation/support/ModelAndViewMethodReturnValueHandler.java
...otation/support/ModelAndViewMethodReturnValueHandler.java
+2
-2
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/annotation/support/RequestResponseBodyMethodProcessor.java
...nnotation/support/RequestResponseBodyMethodProcessor.java
+3
-4
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/annotation/support/ServletRequestMethodArgumentResolver.java
...otation/support/ServletRequestMethodArgumentResolver.java
+2
-2
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/annotation/support/ServletResponseMethodArgumentResolver.java
...tation/support/ServletResponseMethodArgumentResolver.java
+8
-4
org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/method/annotation/ControllerMethodAnnotationDetectionTests.java
.../annotation/ControllerMethodAnnotationDetectionTests.java
+4
-7
org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/method/annotation/ServletInvocableHandlerMethodTests.java
...method/annotation/ServletInvocableHandlerMethodTests.java
+2
-1
org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/method/annotation/support/HttpEntityMethodProcessorTests.java
...od/annotation/support/HttpEntityMethodProcessorTests.java
+20
-11
org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/method/annotation/support/RequestResponseBodyMethodProcessorTests.java
...tion/support/RequestResponseBodyMethodProcessorTests.java
+12
-5
org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/method/annotation/support/ServletResponseMethodArgumentResolverTests.java
...n/support/ServletResponseMethodArgumentResolverTests.java
+11
-5
org.springframework.web/.settings/org.eclipse.jdt.core.prefs
org.springframework.web/.settings/org.eclipse.jdt.core.prefs
+1
-257
org.springframework.web/.settings/org.eclipse.jdt.ui.prefs
org.springframework.web/.settings/org.eclipse.jdt.ui.prefs
+1
-2
org.springframework.web/src/main/java/org/springframework/web/method/HandlerMethod.java
...in/java/org/springframework/web/method/HandlerMethod.java
+1
-1
org.springframework.web/src/main/java/org/springframework/web/method/HandlerMethodSelector.java
...org/springframework/web/method/HandlerMethodSelector.java
+2
-1
org.springframework.web/src/main/java/org/springframework/web/method/annotation/InitBinderMethodDataBinderFactory.java
.../method/annotation/InitBinderMethodDataBinderFactory.java
+7
-7
org.springframework.web/src/main/java/org/springframework/web/method/annotation/ModelFactory.java
...g/springframework/web/method/annotation/ModelFactory.java
+66
-74
org.springframework.web/src/main/java/org/springframework/web/method/annotation/SessionAttributesHandler.java
...ework/web/method/annotation/SessionAttributesHandler.java
+2
-1
org.springframework.web/src/main/java/org/springframework/web/method/annotation/support/AbstractNamedValueMethodArgumentResolver.java
...ion/support/AbstractNamedValueMethodArgumentResolver.java
+2
-2
org.springframework.web/src/main/java/org/springframework/web/method/annotation/support/ErrorsMethodArgumentResolver.java
...thod/annotation/support/ErrorsMethodArgumentResolver.java
+3
-1
org.springframework.web/src/main/java/org/springframework/web/method/annotation/support/ModelAttributeMethodProcessor.java
...hod/annotation/support/ModelAttributeMethodProcessor.java
+12
-17
org.springframework.web/src/main/java/org/springframework/web/method/annotation/support/ModelMethodProcessor.java
...k/web/method/annotation/support/ModelMethodProcessor.java
+4
-14
org.springframework.web/src/main/java/org/springframework/web/method/annotation/support/RequestHeaderMapMethodArgumentResolver.java
...ation/support/RequestHeaderMapMethodArgumentResolver.java
+3
-3
org.springframework.web/src/main/java/org/springframework/web/method/annotation/support/RequestParamMapMethodArgumentResolver.java
...tation/support/RequestParamMapMethodArgumentResolver.java
+2
-2
org.springframework.web/src/main/java/org/springframework/web/method/annotation/support/WebArgumentResolverAdapter.java
...method/annotation/support/WebArgumentResolverAdapter.java
+2
-2
org.springframework.web/src/main/java/org/springframework/web/method/support/HandlerMethodArgumentResolver.java
...ork/web/method/support/HandlerMethodArgumentResolver.java
+11
-12
org.springframework.web/src/main/java/org/springframework/web/method/support/HandlerMethodArgumentResolverComposite.java
...ethod/support/HandlerMethodArgumentResolverComposite.java
+14
-26
org.springframework.web/src/main/java/org/springframework/web/method/support/HandlerMethodProcessor.java
...gframework/web/method/support/HandlerMethodProcessor.java
+0
-39
org.springframework.web/src/main/java/org/springframework/web/method/support/HandlerMethodReturnValueHandler.java
...k/web/method/support/HandlerMethodReturnValueHandler.java
+12
-9
org.springframework.web/src/main/java/org/springframework/web/method/support/HandlerMethodReturnValueHandlerComposite.java
...hod/support/HandlerMethodReturnValueHandlerComposite.java
+18
-32
org.springframework.web/src/main/java/org/springframework/web/method/support/InvocableHandlerMethod.java
...gframework/web/method/support/InvocableHandlerMethod.java
+38
-49
org.springframework.web/src/main/java/org/springframework/web/method/support/ModelAndViewContainer.java
...ngframework/web/method/support/ModelAndViewContainer.java
+97
-19
org.springframework.web/src/test/java/org/springframework/web/method/annotation/ModelFactoryTests.java
...ingframework/web/method/annotation/ModelFactoryTests.java
+22
-21
org.springframework.web/src/test/java/org/springframework/web/method/annotation/support/ErrorsMethodHandlerArgumentResolverTests.java
...ion/support/ErrorsMethodHandlerArgumentResolverTests.java
+21
-23
org.springframework.web/src/test/java/org/springframework/web/method/annotation/support/ModelAttributeMethodProcessorTests.java
...nnotation/support/ModelAttributeMethodProcessorTests.java
+11
-13
org.springframework.web/src/test/java/org/springframework/web/method/annotation/support/ModelMethodProcessorTests.java
.../method/annotation/support/ModelMethodProcessorTests.java
+5
-5
org.springframework.web/src/test/java/org/springframework/web/method/support/HandlerMethodArgumentResolverCompositeTests.java
.../support/HandlerMethodArgumentResolverCompositeTests.java
+0
-12
org.springframework.web/src/test/java/org/springframework/web/method/support/HandlerMethodReturnValueHandlerCompositeTests.java
...upport/HandlerMethodReturnValueHandlerCompositeTests.java
+1
-13
org.springframework.web/src/test/java/org/springframework/web/method/support/InvocableHandlerMethodTests.java
...ework/web/method/support/InvocableHandlerMethodTests.java
+0
-9
org.springframework.web/src/test/java/org/springframework/web/method/support/StubArgumentResolver.java
...ingframework/web/method/support/StubArgumentResolver.java
+4
-4
org.springframework.web/src/test/java/org/springframework/web/method/support/StubReturnValueHandler.java
...gframework/web/method/support/StubReturnValueHandler.java
+1
-1
未找到文件。
org.springframework.web.servlet/.settings/org.eclipse.jdt.core.prefs
浏览文件 @
6fe0ff9e
此差异已折叠。
点击以展开。
org.springframework.web.servlet/.settings/org.eclipse.jdt.ui.prefs
浏览文件 @
6fe0ff9e
#
Mon Jul 27 18:14:39 EDT 2009
#
Thu Apr 07 14:34:40 BST 2011
eclipse.preferences.version=1
formatter_profile=_Spring
formatter_settings_version=11
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerMethodAdapter.java
浏览文件 @
6fe0ff9e
...
...
@@ -41,7 +41,6 @@ import org.springframework.http.converter.HttpMessageConverter;
import
org.springframework.http.converter.StringHttpMessageConverter
;
import
org.springframework.http.converter.xml.SourceHttpMessageConverter
;
import
org.springframework.http.converter.xml.XmlAwareFormHttpMessageConverter
;
import
org.springframework.ui.ModelMap
;
import
org.springframework.util.ReflectionUtils.MethodFilter
;
import
org.springframework.web.bind.annotation.InitBinder
;
import
org.springframework.web.bind.annotation.ModelAttribute
;
...
...
@@ -67,13 +66,14 @@ import org.springframework.web.method.annotation.support.RequestHeaderMapMethodA
import
org.springframework.web.method.annotation.support.RequestHeaderMethodArgumentResolver
;
import
org.springframework.web.method.annotation.support.RequestParamMapMethodArgumentResolver
;
import
org.springframework.web.method.annotation.support.RequestParamMethodArgumentResolver
;
import
org.springframework.web.method.annotation.support.WebArgumentResolverAdapter
;
import
org.springframework.web.method.support.HandlerMethodArgumentResolver
;
import
org.springframework.web.method.support.HandlerMethodArgumentResolverComposite
;
import
org.springframework.web.method.support.HandlerMethodReturnValueHandler
;
import
org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite
;
import
org.springframework.web.method.support.InvocableHandlerMethod
;
import
org.springframework.web.method.support.ModelAndViewContainer
;
import
org.springframework.web.servlet.ModelAndView
;
import
org.springframework.web.servlet.View
;
import
org.springframework.web.servlet.mvc.annotation.ModelAndViewResolver
;
import
org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter
;
import
org.springframework.web.servlet.mvc.method.annotation.support.DefaultMethodReturnValueHandler
;
...
...
@@ -459,13 +459,25 @@ public class RequestMappingHandlerMethodAdapter extends AbstractHandlerMethodAda
ServletWebRequest
webRequest
=
new
ServletWebRequest
(
request
,
response
);
SessionStatus
sessionStatus
=
new
SimpleSessionStatus
();
Model
Map
implicitModel
=
modelFactory
.
createModel
(
webRequest
,
requestMethod
);
ModelAndView
mav
=
requestMethod
.
invokeAndHandle
(
webRequest
,
implicitModel
,
sessionStatus
);
ModelMap
actualModel
=
(
mav
!=
null
)
?
mav
.
getModelMap
()
:
null
;
modelFactory
.
updateAttributes
(
webRequest
,
sessionStatus
,
actualModel
,
implicitModel
);
Model
AndViewContainer
mavContainer
=
new
ModelAndViewContainer
(
);
modelFactory
.
initModel
(
webRequest
,
mavContainer
,
requestMethod
);
requestMethod
.
invokeAndHandle
(
webRequest
,
mavContainer
,
sessionStatus
);
return
mav
;
modelFactory
.
updateModel
(
webRequest
,
mavContainer
,
sessionStatus
);
if
(!
mavContainer
.
isResolveView
())
{
return
null
;
}
else
{
ModelAndView
mav
=
new
ModelAndView
().
addAllObjects
(
mavContainer
.
getModel
());
mav
.
setViewName
(
mavContainer
.
getViewName
());
if
(
mavContainer
.
getView
()
!=
null
)
{
mav
.
setView
((
View
)
mavContainer
.
getView
());
}
return
mav
;
}
}
private
WebDataBinderFactory
createDataBinderFactory
(
HandlerMethod
handlerMethod
)
{
...
...
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerMethodExceptionResolver.java
浏览文件 @
6fe0ff9e
...
...
@@ -32,8 +32,6 @@ import org.springframework.http.converter.HttpMessageConverter;
import
org.springframework.http.converter.StringHttpMessageConverter
;
import
org.springframework.http.converter.xml.SourceHttpMessageConverter
;
import
org.springframework.http.converter.xml.XmlAwareFormHttpMessageConverter
;
import
org.springframework.ui.ExtendedModelMap
;
import
org.springframework.ui.ModelMap
;
import
org.springframework.util.ReflectionUtils.MethodFilter
;
import
org.springframework.web.bind.annotation.ExceptionHandler
;
import
org.springframework.web.bind.support.WebArgumentResolver
;
...
...
@@ -47,9 +45,10 @@ import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import
org.springframework.web.method.support.HandlerMethodArgumentResolverComposite
;
import
org.springframework.web.method.support.HandlerMethodReturnValueHandler
;
import
org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite
;
import
org.springframework.web.method.support.ModelAndViewContainer
;
import
org.springframework.web.servlet.ModelAndView
;
import
org.springframework.web.servlet.View
;
import
org.springframework.web.servlet.handler.AbstractHandlerMethodExceptionResolver
;
import
org.springframework.web.servlet.mvc.annotation.ModelAndViewResolver
;
import
org.springframework.web.servlet.mvc.method.annotation.support.DefaultMethodReturnValueHandler
;
import
org.springframework.web.servlet.mvc.method.annotation.support.HttpEntityMethodProcessor
;
import
org.springframework.web.servlet.mvc.method.annotation.support.ModelAndViewMethodReturnValueHandler
;
...
...
@@ -60,17 +59,15 @@ import org.springframework.web.servlet.mvc.method.annotation.support.ServletWebA
import
org.springframework.web.servlet.mvc.method.annotation.support.ViewMethodReturnValueHandler
;
/**
* An extension of {@link AbstractHandlerMethodExceptionResolver} that matches thrown exceptions to
* {@link ExceptionHandler @ExceptionHandler} methods in the handler. If a match is found the
* exception-handling method is invoked to process the request.
* A {@link AbstractHandlerMethodExceptionResolver} that matches thrown exceptions to {@link ExceptionHandler}-annotated
* methods. If a match is found the exception-handling method is invoked to process the request.
*
* <p>See {@link ExceptionHandler} for information on supported method arguments and return values
*
for exception-handling methods. You can customize method argument resolution and return value
*
processing through the various bean properties
in this class.
* <p>See {@link ExceptionHandler} for information on supported method arguments and return values
for exception-handling
*
methods. You can customize method argument resolution and return value processing through the various bean properties
* in this class.
*
* @author Rossen Stoyanchev
* @since 3.1
* @see #setMessageConverters(HttpMessageConverter[])
*/
public
class
RequestMappingHandlerMethodExceptionResolver
extends
AbstractHandlerMethodExceptionResolver
implements
InitializingBean
{
...
...
@@ -79,8 +76,6 @@ public class RequestMappingHandlerMethodExceptionResolver extends AbstractHandle
private
HttpMessageConverter
<?>[]
messageConverters
;
private
ModelAndViewResolver
[]
customModelAndViewResolvers
;
private
final
Map
<
Class
<?>,
ExceptionMethodMapping
>
exceptionMethodMappingCache
=
new
ConcurrentHashMap
<
Class
<?>,
ExceptionMethodMapping
>();
...
...
@@ -102,9 +97,11 @@ public class RequestMappingHandlerMethodExceptionResolver extends AbstractHandle
}
/**
* Set a custom ArgumentResolver
s
to use for special method parameter types.
* Set a custom ArgumentResolver to use for special method parameter types.
* <p>Such a custom ArgumentResolver will kick in first, having a chance to resolve
* an argument value before the standard argument handling kicks in.
* <p>Note: this is provided for backward compatibility. The preferred way to do this is to
* implement a {@link HandlerMethodArgumentResolver}.
*/
public
void
setCustomArgumentResolver
(
WebArgumentResolver
argumentResolver
)
{
this
.
customArgumentResolvers
=
new
WebArgumentResolver
[]{
argumentResolver
};
...
...
@@ -114,6 +111,8 @@ public class RequestMappingHandlerMethodExceptionResolver extends AbstractHandle
* Set one or more custom ArgumentResolvers to use for special method parameter types.
* <p>Any such custom ArgumentResolver will kick in first, having a chance to resolve
* an argument value before the standard argument handling kicks in.
* <p>Note: this is provided for backward compatibility. The preferred way to do this is to
* implement a {@link HandlerMethodArgumentResolver}.
*/
public
void
setCustomArgumentResolvers
(
WebArgumentResolver
[]
argumentResolvers
)
{
this
.
customArgumentResolvers
=
argumentResolvers
;
...
...
@@ -127,24 +126,6 @@ public class RequestMappingHandlerMethodExceptionResolver extends AbstractHandle
this
.
messageConverters
=
messageConverters
;
}
/**
* Set a custom ModelAndViewResolvers to use for special method return types.
* <p>Such a custom ModelAndViewResolver will kick in first, having a chance to resolve
* a return value before the standard ModelAndView handling kicks in.
*/
public
void
setCustomModelAndViewResolver
(
ModelAndViewResolver
customModelAndViewResolver
)
{
this
.
customModelAndViewResolvers
=
new
ModelAndViewResolver
[]
{
customModelAndViewResolver
};
}
/**
* Set one or more custom ModelAndViewResolvers to use for special method return types.
* <p>Any such custom ModelAndViewResolver will kick in first, having a chance to resolve
* a return value before the standard ModelAndView handling kicks in.
*/
public
void
setCustomModelAndViewResolvers
(
ModelAndViewResolver
[]
customModelAndViewResolvers
)
{
this
.
customModelAndViewResolvers
=
customModelAndViewResolvers
;
}
/**
* Set the {@link HandlerMethodArgumentResolver}s to use to resolve argument values for
* {@link ExceptionHandler} methods. This is an optional property.
...
...
@@ -207,9 +188,14 @@ public class RequestMappingHandlerMethodExceptionResolver extends AbstractHandle
returnValueHandlers
.
registerReturnValueHandler
(
new
HttpEntityMethodProcessor
(
messageConverters
));
// Default handler
returnValueHandlers
.
registerReturnValueHandler
(
new
DefaultMethodReturnValueHandler
(
customModelAndViewResolvers
));
returnValueHandlers
.
registerReturnValueHandler
(
new
DefaultMethodReturnValueHandler
(
null
));
}
/**
* Attempts to find an {@link ExceptionHandler}-annotated method that can handle the thrown exception.
* The exception-handling method, if found, is invoked resulting in a {@link ModelAndView}.
* @return a {@link ModelAndView} if a matching exception-handling method was found, or {@code null} otherwise
*/
@Override
protected
ModelAndView
doResolveHandlerMethodException
(
HttpServletRequest
request
,
HttpServletResponse
response
,
...
...
@@ -226,13 +212,25 @@ public class RequestMappingHandlerMethodExceptionResolver extends AbstractHandle
exceptionHandler
.
setHandlerMethodReturnValueHandlers
(
returnValueHandlers
);
ServletWebRequest
webRequest
=
new
ServletWebRequest
(
request
,
response
);
ModelMap
model
=
new
ExtendedModelMap
();
try
{
if
(
logger
.
isDebugEnabled
())
{
logger
.
debug
(
"Invoking exception-handling method: "
+
exceptionHandler
);
}
ModelAndView
mav
=
exceptionHandler
.
invokeAndHandle
(
webRequest
,
model
,
ex
);
return
(
mav
!=
null
)
?
mav
:
new
ModelAndView
();
ModelAndViewContainer
mavContainer
=
new
ModelAndViewContainer
();
exceptionHandler
.
invokeAndHandle
(
webRequest
,
mavContainer
,
ex
);
if
(!
mavContainer
.
isResolveView
())
{
return
new
ModelAndView
();
}
else
{
ModelAndView
mav
=
new
ModelAndView
().
addAllObjects
(
mavContainer
.
getModel
());
mav
.
setViewName
(
mavContainer
.
getViewName
());
if
(
mavContainer
.
getView
()
!=
null
)
{
mav
.
setView
((
View
)
mavContainer
.
getView
());
}
return
mav
;
}
}
catch
(
Exception
invocationEx
)
{
logger
.
error
(
"Invoking exception-handling method resulted in exception : "
+
...
...
@@ -244,6 +242,9 @@ public class RequestMappingHandlerMethodExceptionResolver extends AbstractHandle
return
null
;
}
/**
* @return an {@link ExceptionMethodMapping} for the the given handler method, never {@code null}
*/
private
ExceptionMethodMapping
getExceptionMethodMapping
(
HandlerMethod
handlerMethod
)
{
Class
<?>
handlerType
=
handlerMethod
.
getBeanType
();
ExceptionMethodMapping
mapping
=
exceptionMethodMappingCache
.
get
(
handlerType
);
...
...
@@ -256,7 +257,7 @@ public class RequestMappingHandlerMethodExceptionResolver extends AbstractHandle
}
/**
*
Pre-built
MethodFilter that matches {@link ExceptionHandler @ExceptionHandler} methods.
* MethodFilter that matches {@link ExceptionHandler @ExceptionHandler} methods.
*/
public
static
MethodFilter
EXCEPTION_HANDLER_METHODS
=
new
MethodFilter
()
{
...
...
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ServletInitBinderMethodDataBinderFactory.java
浏览文件 @
6fe0ff9e
...
...
@@ -43,7 +43,7 @@ public class ServletInitBinderMethodDataBinderFactory extends InitBinderMethodDa
}
/**
*
{@inheritDoc} c
reates a Servlet data binder.
*
C
reates a Servlet data binder.
*/
@Override
protected
WebDataBinder
createBinderInstance
(
Object
target
,
String
objectName
)
{
...
...
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ServletInvocableHandlerMethod.java
浏览文件 @
6fe0ff9e
...
...
@@ -20,23 +20,31 @@ import java.io.IOException;
import
java.lang.reflect.Method
;
import
org.springframework.http.HttpStatus
;
import
org.springframework.ui.ModelMap
;
import
org.springframework.util.StringUtils
;
import
org.springframework.web.bind.annotation.ResponseStatus
;
import
org.springframework.web.bind.support.SessionStatus
;
import
org.springframework.web.context.request.NativeWebRequest
;
import
org.springframework.web.context.request.ServletWebRequest
;
import
org.springframework.web.method.support.HandlerMethodArgumentResolver
;
import
org.springframework.web.method.support.HandlerMethodReturnValueHandler
;
import
org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite
;
import
org.springframework.web.method.support.InvocableHandlerMethod
;
import
org.springframework.web.method.support.ModelAndViewContainer
;
import
org.springframework.web.servlet.HandlerAdapter
;
import
org.springframework.web.servlet.ModelAndView
;
import
org.springframework.web.servlet.View
;
/**
* Extends {@link InvocableHandlerMethod} with the ability to handle the return value of the invocation
* resulting in a {@link ModelAndView} according to the {@link HandlerAdapter} contract.
* Extends {@link InvocableHandlerMethod} with the ability to handle the return value through registered
* {@link HandlerMethodArgumentResolver}s. If the handler method is annotated with {@link ResponseStatus},
* the status on the response is set accordingly after method invocation but before return value handling.
*
* <p>Return value handling may be skipped entirely if the handler method returns a {@code null} (or is a
* {@code void} method) and one of the following other conditions is true:
* <ul>
* <li>One of the {@link HandlerMethodArgumentResolver}s set the {@link ModelAndViewContainer#setResolveView(boolean)}
* flag to {@code false}. This is the case when a method argument allows the handler method access to the response.
* <li>The request qualifies as being not modified according to {@link ServletWebRequest#isNotModified()}.
* This is used in conjunction with a "Last-Modified" header or ETag.
* <li>The status on the response was set as a result of a {@link ResponseStatus} annotation
* </ul>
*
* @author Rossen Stoyanchev
* @since 3.1
...
...
@@ -70,36 +78,47 @@ public class ServletInvocableHandlerMethod extends InvocableHandlerMethod {
}
/**
* Invokes the method via {@link #invokeForRequest(NativeWebRequest, ModelMap, Object...)} and also handles the
* return value by invoking one of the {@link HandlerMethodReturnValueHandler} instances registered via
* {@link #setHandlerMethodReturnValueHandlers(HandlerMethodReturnValueHandlerComposite)}.
* If the method is annotated with {@link SessionStatus} the response status will be set.
* Invokes the method and handles the return value through registered {@link HandlerMethodReturnValueHandler}s.
* If the handler method is annotated with {@link ResponseStatus}, the status on the response is set accordingly
* after method invocation but before return value handling.
* <p>Return value handling may be skipped entirely if the handler method returns a {@code null} (or is a
* {@code void} method) and one of the following other conditions is true:
* <ul>
* <li>One of the {@link HandlerMethodArgumentResolver}s set the {@link ModelAndViewContainer#setResolveView(boolean)}
* flag to {@code false}. This is the case when a method argument allows the handler method access to the response.
* <li>The request qualifies as being not modified according to {@link ServletWebRequest#isNotModified()}.
* This is used in conjunction with a "Last-Modified" header or ETag.
* <li>The status on the response was set as a result of a {@link ResponseStatus} annotation
* </ul>
* <p>After the call, use the {@link ModelAndViewContainer} parameter to access model attributes and view selection
* and to determine if view resolution is needed.
*
* @param request the current request
* @param model the model used throughout the current request
* @param providedArgs argument values to use as-is if they match to a method parameter's type
* @return ModelAndView object with the name of the view and the required model data, or <code>null</code>
* if the response was handled
* @param mavContainer the {@link ModelAndViewContainer} for the current request
* @param providedArgs argument values to try to use without the need for view resolution
*/
public
final
ModelAndView
invokeAndHandle
(
NativeWebRequest
request
,
ModelMap
model
,
Object
...
providedArgs
)
throws
Exception
{
public
final
void
invokeAndHandle
(
NativeWebRequest
request
,
ModelAndViewContainer
mavContainer
,
Object
...
providedArgs
)
throws
Exception
{
if
(!
returnValueHandlers
.
supportsReturnType
(
getReturnType
()))
{
throw
new
IllegalStateException
(
"No suitable HandlerMethodReturnValueHandler for method "
+
toString
());
}
Object
returnValue
=
invokeForRequest
(
request
,
m
odel
,
providedArgs
);
Object
returnValue
=
invokeForRequest
(
request
,
m
avContainer
,
providedArgs
);
setResponseStatus
((
ServletWebRequest
)
request
);
if
(
returnValue
==
null
&&
(
isRequestNotModified
(
request
)
||
usesResponseArgument
()))
{
return
null
;
if
(
returnValue
==
null
)
{
if
(
isRequestNotModified
(
request
)
||
hasResponseStatus
()
||
!
mavContainer
.
isResolveView
())
{
mavContainer
.
setResolveView
(
false
);
return
;
}
}
ModelAndViewContainer
mavContainer
=
new
ModelAndViewContainer
(
model
);
returnValueHandlers
.
handleReturnValue
(
returnValue
,
getReturnType
(),
mavContainer
,
request
);
mavContainer
.
setResolveView
(
true
);
return
getModelAndView
(
request
,
mavContainer
,
returnValue
);
return
ValueHandlers
.
handleReturnValue
(
returnValue
,
getReturnType
(),
mavContainer
,
request
);
}
/**
...
...
@@ -120,38 +139,17 @@ public class ServletInvocableHandlerMethod extends InvocableHandlerMethod {
}
/**
*
Create a {@link ModelAndView} from a {@link ModelAndViewContainer}.
*
Does the request qualify as not modified?
*/
private
ModelAndView
getModelAndView
(
NativeWebRequest
request
,
ModelAndViewContainer
mavContainer
,
Object
returnValue
)
{
if
(
returnValueHandlerUsesResponseArgument
())
{
return
null
;
}
else
{
ModelAndView
mav
=
new
ModelAndView
().
addAllObjects
(
mavContainer
.
getModel
());
mav
.
setViewName
(
mavContainer
.
getViewName
());
if
(
mavContainer
.
getView
()
!=
null
)
{
mav
.
setView
((
View
)
mavContainer
.
getView
());
}
return
mav
;
}
private
boolean
isRequestNotModified
(
NativeWebRequest
request
)
{
return
((
ServletWebRequest
)
request
).
isNotModified
();
}
/**
* Check whether the request qualifies as not modified...
* TODO: document fully including sample user code
* Does the method set the response status?
*/
private
boolean
isRequestNotModified
(
NativeWebRequest
request
)
{
ServletWebRequest
servletRequest
=
(
ServletWebRequest
)
request
;
return
(
servletRequest
.
isNotModified
()
||
(
responseStatus
!=
null
)
||
usesResponseArgument
());
}
protected
boolean
usesResponseArgument
()
{
return
(
super
.
usesResponseArgument
()
||
returnValueHandlerUsesResponseArgument
()
||
(
responseStatus
!=
null
));
private
boolean
hasResponseStatus
()
{
return
responseStatus
!=
null
;
}
private
boolean
returnValueHandlerUsesResponseArgument
()
{
return
returnValueHandlers
.
usesResponseArgument
(
getReturnType
());
}
}
}
\ No newline at end of file
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/annotation/support/DefaultMethodReturnValueHandler.java
浏览文件 @
6fe0ff9e
...
...
@@ -68,7 +68,7 @@ public class DefaultMethodReturnValueHandler implements HandlerMethodReturnValue
if
(
mav
!=
ModelAndViewResolver
.
UNRESOLVED
)
{
mavContainer
.
setView
(
mav
.
getView
());
mavContainer
.
setViewName
(
mav
.
getViewName
());
mavContainer
.
add
Mode
lAttributes
(
mav
.
getModel
());
mavContainer
.
add
Al
lAttributes
(
mav
.
getModel
());
return
;
}
}
...
...
@@ -78,7 +78,7 @@ public class DefaultMethodReturnValueHandler implements HandlerMethodReturnValue
}
else
if
(!
BeanUtils
.
isSimpleProperty
(
returnValue
.
getClass
()))
{
String
name
=
ModelFactory
.
getNameForReturnValue
(
returnValue
,
returnType
);
mavContainer
.
add
Model
Attribute
(
name
,
returnValue
);
mavContainer
.
addAttribute
(
name
,
returnValue
);
}
// should not happen
...
...
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/annotation/support/HttpEntityMethodProcessor.java
浏览文件 @
6fe0ff9e
...
...
@@ -35,7 +35,6 @@ import org.springframework.http.converter.HttpMessageConverter;
import
org.springframework.http.server.ServerHttpResponse
;
import
org.springframework.http.server.ServletServerHttpRequest
;
import
org.springframework.http.server.ServletServerHttpResponse
;
import
org.springframework.ui.ModelMap
;
import
org.springframework.util.Assert
;
import
org.springframework.web.HttpMediaTypeNotSupportedException
;
import
org.springframework.web.bind.support.WebDataBinderFactory
;
...
...
@@ -74,7 +73,7 @@ public class HttpEntityMethodProcessor extends AbstractMessageConverterMethodPro
}
public
Object
resolveArgument
(
MethodParameter
parameter
,
Model
Map
model
,
Model
AndViewContainer
mavContainer
,
NativeWebRequest
webRequest
,
WebDataBinderFactory
binderFactory
)
throws
IOException
,
HttpMediaTypeNotSupportedException
{
...
...
@@ -116,19 +115,25 @@ public class HttpEntityMethodProcessor extends AbstractMessageConverterMethodPro
MethodParameter
returnType
,
ModelAndViewContainer
mavContainer
,
NativeWebRequest
webRequest
)
throws
Exception
{
mavContainer
.
setResolveView
(
false
);
if
(
returnValue
==
null
)
{
return
;
}
HttpOutputMessage
outputMessage
=
createOutputMessage
(
webRequest
);
Assert
.
isInstanceOf
(
HttpEntity
.
class
,
returnValue
);
HttpEntity
<?>
responseEntity
=
(
HttpEntity
<?>)
returnValue
;
HttpOutputMessage
outputMessage
=
createOutputMessage
(
webRequest
);
if
(
responseEntity
instanceof
ResponseEntity
)
{
((
ServerHttpResponse
)
outputMessage
).
setStatusCode
(((
ResponseEntity
<?>)
responseEntity
).
getStatusCode
());
}
HttpHeaders
entityHeaders
=
responseEntity
.
getHeaders
();
if
(!
entityHeaders
.
isEmpty
())
{
outputMessage
.
getHeaders
().
putAll
(
entityHeaders
);
}
Object
body
=
responseEntity
.
getBody
();
if
(
body
!=
null
)
{
writeWithMessageConverters
(
body
,
createInputMessage
(
webRequest
),
outputMessage
);
...
...
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/annotation/support/ModelAndViewMethodReturnValueHandler.java
浏览文件 @
6fe0ff9e
...
...
@@ -46,10 +46,10 @@ public class ModelAndViewMethodReturnValueHandler implements HandlerMethodReturn
ModelAndView
mav
=
(
ModelAndView
)
returnValue
;
mavContainer
.
setView
(
mav
.
getView
());
mavContainer
.
setViewName
(
mav
.
getViewName
());
mavContainer
.
add
Mode
lAttributes
(
mav
.
getModel
());
mavContainer
.
add
Al
lAttributes
(
mav
.
getModel
());
}
else
{
// TODO
mavContainer
.
setResolveView
(
false
);
}
}
...
...
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/annotation/support/RequestResponseBodyMethodProcessor.java
浏览文件 @
6fe0ff9e
...
...
@@ -27,7 +27,6 @@ import org.springframework.http.HttpOutputMessage;
import
org.springframework.http.converter.HttpMessageConverter
;
import
org.springframework.http.server.ServletServerHttpRequest
;
import
org.springframework.http.server.ServletServerHttpResponse
;
import
org.springframework.ui.ModelMap
;
import
org.springframework.web.HttpMediaTypeNotAcceptableException
;
import
org.springframework.web.HttpMediaTypeNotSupportedException
;
import
org.springframework.web.bind.annotation.RequestBody
;
...
...
@@ -66,7 +65,7 @@ public class RequestResponseBodyMethodProcessor extends AbstractMessageConverter
}
public
Object
resolveArgument
(
MethodParameter
parameter
,
Model
Map
model
,
Model
AndViewContainer
mavContainer
,
NativeWebRequest
webRequest
,
WebDataBinderFactory
binderFactory
)
throws
IOException
,
HttpMediaTypeNotSupportedException
{
...
...
@@ -82,8 +81,8 @@ public class RequestResponseBodyMethodProcessor extends AbstractMessageConverter
public
void
handleReturnValue
(
Object
returnValue
,
MethodParameter
returnType
,
ModelAndViewContainer
mavContainer
,
NativeWebRequest
webRequest
)
throws
IOException
,
HttpMediaTypeNotAcceptableException
{
NativeWebRequest
webRequest
)
throws
IOException
,
HttpMediaTypeNotAcceptableException
{
mavContainer
.
setResolveView
(
false
);
if
(
returnValue
!=
null
)
{
writeWithMessageConverters
(
webRequest
,
returnValue
);
}
...
...
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/annotation/support/ServletRequestMethodArgumentResolver.java
浏览文件 @
6fe0ff9e
...
...
@@ -27,10 +27,10 @@ import javax.servlet.http.HttpServletRequest;
import
javax.servlet.http.HttpSession
;
import
org.springframework.core.MethodParameter
;
import
org.springframework.ui.ModelMap
;
import
org.springframework.web.bind.support.WebDataBinderFactory
;
import
org.springframework.web.context.request.NativeWebRequest
;
import
org.springframework.web.method.support.HandlerMethodArgumentResolver
;
import
org.springframework.web.method.support.ModelAndViewContainer
;
import
org.springframework.web.multipart.MultipartRequest
;
import
org.springframework.web.servlet.support.RequestContextUtils
;
...
...
@@ -55,7 +55,7 @@ public class ServletRequestMethodArgumentResolver implements HandlerMethodArgume
}
public
Object
resolveArgument
(
MethodParameter
parameter
,
Model
Map
model
,
Model
AndViewContainer
mavContainer
,
NativeWebRequest
webRequest
,
WebDataBinderFactory
binderFactory
)
throws
IOException
{
HttpServletRequest
request
=
webRequest
.
getNativeRequest
(
HttpServletRequest
.
class
);
...
...
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/annotation/support/ServletResponseMethodArgumentResolver.java
浏览文件 @
6fe0ff9e
...
...
@@ -24,10 +24,10 @@ import javax.servlet.ServletResponse;
import
javax.servlet.http.HttpServletResponse
;
import
org.springframework.core.MethodParameter
;
import
org.springframework.ui.ModelMap
;
import
org.springframework.web.bind.support.WebDataBinderFactory
;
import
org.springframework.web.context.request.NativeWebRequest
;
import
org.springframework.web.method.support.HandlerMethodArgumentResolver
;
import
org.springframework.web.method.support.ModelAndViewContainer
;
/**
* Implementation of {@link HandlerMethodArgumentResolver} that supports {@link ServletResponse} and related arguments.
...
...
@@ -47,12 +47,14 @@ public class ServletResponseMethodArgumentResolver implements HandlerMethodArgum
}
public
Object
resolveArgument
(
MethodParameter
parameter
,
Model
Map
model
,
Model
AndViewContainer
mavContainer
,
NativeWebRequest
webRequest
,
WebDataBinderFactory
binderFactory
)
throws
IOException
{
HttpServletResponse
response
=
webRequest
.
getNativeResponse
(
HttpServletResponse
.
class
);
Class
<?>
parameterType
=
parameter
.
getParameterType
();
mavContainer
.
setResolveView
(
false
);
if
(
ServletResponse
.
class
.
isAssignableFrom
(
parameterType
))
{
Object
nativeResponse
=
webRequest
.
getNativeResponse
(
parameterType
);
if
(
nativeResponse
==
null
)
{
...
...
@@ -67,7 +69,9 @@ public class ServletResponseMethodArgumentResolver implements HandlerMethodArgum
else
if
(
Writer
.
class
.
isAssignableFrom
(
parameterType
))
{
return
response
.
getWriter
();
}
// should not happen
throw
new
UnsupportedOperationException
();
else
{
// should not happen
throw
new
UnsupportedOperationException
();
}
}
}
org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/method/annotation/ControllerMethodAnnotationDetectionTests.java
浏览文件 @
6fe0ff9e
...
...
@@ -35,8 +35,6 @@ import org.springframework.beans.factory.support.RootBeanDefinition;
import
org.springframework.core.annotation.AnnotationUtils
;
import
org.springframework.mock.web.MockHttpServletRequest
;
import
org.springframework.mock.web.MockHttpServletResponse
;
import
org.springframework.ui.ExtendedModelMap
;
import
org.springframework.ui.ModelMap
;
import
org.springframework.util.ClassUtils
;
import
org.springframework.util.ReflectionUtils.MethodFilter
;
import
org.springframework.web.bind.annotation.ModelAttribute
;
...
...
@@ -49,8 +47,7 @@ import org.springframework.web.method.HandlerMethodSelector;
import
org.springframework.web.method.annotation.support.ModelAttributeMethodProcessor
;
import
org.springframework.web.method.support.HandlerMethodArgumentResolverComposite
;
import
org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite
;
import
org.springframework.web.servlet.ModelAndView
;
import
org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod
;
import
org.springframework.web.method.support.ModelAndViewContainer
;
import
org.springframework.web.servlet.mvc.method.annotation.support.DefaultMethodReturnValueHandler
;
/**
...
...
@@ -106,10 +103,10 @@ public class ControllerMethodAnnotationDetectionTests {
NativeWebRequest
webRequest
=
new
ServletWebRequest
(
servletRequest
,
new
MockHttpServletResponse
());
servletRequest
.
setParameter
(
"name"
,
"Chad"
);
Model
Map
model
=
new
ExtendedModelMap
();
ModelAndView
mav
=
requestMappingMethod
.
invokeAndHandle
(
webRequest
,
model
);
Model
AndViewContainer
mavContainer
=
new
ModelAndViewContainer
();
requestMappingMethod
.
invokeAndHandle
(
webRequest
,
mavContainer
);
Object
modelAttr
=
mav
.
getModelMap
().
get
(
"attrName"
);
Object
modelAttr
=
mav
Container
.
getAttribute
(
"attrName"
);
assertEquals
(
TestBean
.
class
,
modelAttr
.
getClass
());
assertEquals
(
"Chad"
,
((
TestBean
)
modelAttr
).
getName
());
...
...
org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/method/annotation/ServletInvocableHandlerMethodTests.java
浏览文件 @
6fe0ff9e
...
...
@@ -28,6 +28,7 @@ import org.springframework.mock.web.MockHttpServletResponse;
import
org.springframework.web.bind.annotation.ResponseStatus
;
import
org.springframework.web.context.request.ServletWebRequest
;
import
org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite
;
import
org.springframework.web.method.support.ModelAndViewContainer
;
import
org.springframework.web.servlet.mvc.method.annotation.support.DefaultMethodReturnValueHandler
;
/**
...
...
@@ -56,7 +57,7 @@ public class ServletInvocableHandlerMethodTests {
ServletInvocableHandlerMethod
handlerMethod
=
new
ServletInvocableHandlerMethod
(
new
Handler
(),
method
);
handlerMethod
.
setHandlerMethodReturnValueHandlers
(
handlers
);
handlerMethod
.
invokeAndHandle
(
webRequest
,
n
ull
);
handlerMethod
.
invokeAndHandle
(
webRequest
,
n
ew
ModelAndViewContainer
()
);
assertEquals
(
HttpStatus
.
BAD_REQUEST
.
value
(),
response
.
getStatus
());
assertEquals
(
"400 Bad Request"
,
response
.
getErrorMessage
());
...
...
org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/method/annotation/support/HttpEntityMethodProcessorTests.java
浏览文件 @
6fe0ff9e
...
...
@@ -46,6 +46,7 @@ import org.springframework.mock.web.MockHttpServletResponse;
import
org.springframework.web.HttpMediaTypeNotAcceptableException
;
import
org.springframework.web.HttpMediaTypeNotSupportedException
;
import
org.springframework.web.context.request.ServletWebRequest
;
import
org.springframework.web.method.support.ModelAndViewContainer
;
import
org.springframework.web.servlet.mvc.method.annotation.support.HttpEntityMethodProcessor
;
/**
...
...
@@ -65,16 +66,18 @@ public class HttpEntityMethodProcessorTests {
private
MethodParameter
intReturnValue
;
private
MethodParameter
httpEntityReturnValue
;
private
MethodParameter
intParameter
;
private
ModelAndViewContainer
mavContainer
;
private
ServletWebRequest
request
;
private
MockHttpServletRequest
servletRequest
;
private
MockHttpServletResponse
servletResponse
;
private
MethodParameter
httpEntityReturnValue
;
private
MethodParameter
intParameter
;
@SuppressWarnings
(
"unchecked"
)
@Before
public
void
setUp
()
throws
Exception
{
...
...
@@ -93,6 +96,8 @@ public class HttpEntityMethodProcessorTests {
Method
other
=
getClass
().
getMethod
(
"otherMethod"
);
intReturnValue
=
new
MethodParameter
(
other
,
-
1
);
mavContainer
=
new
ModelAndViewContainer
();
servletRequest
=
new
MockHttpServletRequest
();
servletResponse
=
new
MockHttpServletResponse
();
request
=
new
ServletWebRequest
(
servletRequest
,
servletResponse
);
...
...
@@ -135,7 +140,7 @@ public class HttpEntityMethodProcessorTests {
replay
(
messageConverter
);
HttpEntity
<?>
result
=
(
HttpEntity
<
String
>)
processor
.
resolveArgument
(
httpEntityParam
,
null
,
request
,
null
);
HttpEntity
<?>
result
=
(
HttpEntity
<
String
>)
processor
.
resolveArgument
(
httpEntityParam
,
mavContainer
,
request
,
null
);
assertEquals
(
"Invalid argument"
,
expected
,
result
.
getBody
());
verify
(
messageConverter
);
...
...
@@ -152,14 +157,14 @@ public class HttpEntityMethodProcessorTests {
replay
(
messageConverter
);
processor
.
resolveArgument
(
httpEntityParam
,
null
,
request
,
null
);
processor
.
resolveArgument
(
httpEntityParam
,
mavContainer
,
request
,
null
);
verify
(
messageConverter
);
}
@Test
(
expected
=
HttpMediaTypeNotSupportedException
.
class
)
public
void
resolveArgumentNoContentType
()
throws
Exception
{
processor
.
resolveArgument
(
httpEntityParam
,
null
,
request
,
null
);
processor
.
resolveArgument
(
httpEntityParam
,
mavContainer
,
request
,
null
);
}
@Test
...
...
@@ -175,8 +180,9 @@ public class HttpEntityMethodProcessorTests {
replay
(
messageConverter
);
processor
.
handleReturnValue
(
returnValue
,
responseEntityReturnValue
,
null
,
request
);
processor
.
handleReturnValue
(
returnValue
,
responseEntityReturnValue
,
mavContainer
,
request
);
assertFalse
(
mavContainer
.
isResolveView
());
verify
(
messageConverter
);
}
...
...
@@ -193,8 +199,9 @@ public class HttpEntityMethodProcessorTests {
replay
(
messageConverter
);
processor
.
handleReturnValue
(
returnValue
,
responseEntityReturnValue
,
null
,
request
);
processor
.
handleReturnValue
(
returnValue
,
responseEntityReturnValue
,
mavContainer
,
request
);
assertFalse
(
mavContainer
.
isResolveView
());
verify
(
messageConverter
);
}
...
...
@@ -205,8 +212,9 @@ public class HttpEntityMethodProcessorTests {
ResponseEntity
<
String
>
returnValue
=
new
ResponseEntity
<
String
>(
responseHeaders
,
HttpStatus
.
ACCEPTED
);
HttpEntityMethodProcessor
processor
=
new
HttpEntityMethodProcessor
(
new
StringHttpMessageConverter
());
processor
.
handleReturnValue
(
returnValue
,
responseEntityReturnValue
,
null
,
request
);
processor
.
handleReturnValue
(
returnValue
,
responseEntityReturnValue
,
mavContainer
,
request
);
assertFalse
(
mavContainer
.
isResolveView
());
assertEquals
(
"headerValue"
,
servletResponse
.
getHeader
(
"header"
));
}
...
...
@@ -217,8 +225,9 @@ public class HttpEntityMethodProcessorTests {
ResponseEntity
<
String
>
returnValue
=
new
ResponseEntity
<
String
>(
"body"
,
responseHeaders
,
HttpStatus
.
ACCEPTED
);
HttpEntityMethodProcessor
processor
=
new
HttpEntityMethodProcessor
(
new
StringHttpMessageConverter
());
processor
.
handleReturnValue
(
returnValue
,
responseEntityReturnValue
,
null
,
request
);
processor
.
handleReturnValue
(
returnValue
,
responseEntityReturnValue
,
mavContainer
,
request
);
assertFalse
(
mavContainer
.
isResolveView
());
assertEquals
(
"headerValue"
,
servletResponse
.
getHeader
(
"header"
));
}
...
...
org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/method/annotation/support/RequestResponseBodyMethodProcessorTests.java
浏览文件 @
6fe0ff9e
...
...
@@ -44,6 +44,7 @@ import org.springframework.web.bind.annotation.RequestBody;
import
org.springframework.web.bind.annotation.ResponseBody
;
import
org.springframework.web.context.request.NativeWebRequest
;
import
org.springframework.web.context.request.ServletWebRequest
;
import
org.springframework.web.method.support.ModelAndViewContainer
;
import
org.springframework.web.servlet.mvc.method.annotation.support.RequestResponseBodyMethodProcessor
;
/**
...
...
@@ -63,6 +64,8 @@ public class RequestResponseBodyMethodProcessorTests {
private
MethodParameter
intReturnValue
;
private
ModelAndViewContainer
mavContainer
;
private
NativeWebRequest
webRequest
;
private
MockHttpServletRequest
servletRequest
;
...
...
@@ -79,6 +82,8 @@ public class RequestResponseBodyMethodProcessorTests {
Method
other
=
getClass
().
getMethod
(
"otherMethod"
);
intReturnValue
=
new
MethodParameter
(
other
,
-
1
);
mavContainer
=
new
ModelAndViewContainer
();
servletRequest
=
new
MockHttpServletRequest
();
MockHttpServletResponse
servletResponse
=
new
MockHttpServletResponse
();
webRequest
=
new
ServletWebRequest
(
servletRequest
,
servletResponse
);
...
...
@@ -116,7 +121,7 @@ public class RequestResponseBodyMethodProcessorTests {
replay
(
messageConverter
);
Object
result
=
processor
.
resolveArgument
(
stringParameter
,
null
,
webRequest
,
null
);
Object
result
=
processor
.
resolveArgument
(
stringParameter
,
mavContainer
,
webRequest
,
null
);
assertEquals
(
"Invalid argument"
,
expected
,
result
);
verify
(
messageConverter
);
...
...
@@ -134,14 +139,14 @@ public class RequestResponseBodyMethodProcessorTests {
replay
(
messageConverter
);
processor
.
resolveArgument
(
stringParameter
,
null
,
webRequest
,
null
);
processor
.
resolveArgument
(
stringParameter
,
mavContainer
,
webRequest
,
null
);
verify
(
messageConverter
);
}
@Test
(
expected
=
HttpMediaTypeNotSupportedException
.
class
)
public
void
resolveArgumentNoContentType
()
throws
Exception
{
processor
.
resolveArgument
(
stringParameter
,
null
,
webRequest
,
null
);
processor
.
resolveArgument
(
stringParameter
,
mavContainer
,
webRequest
,
null
);
}
@Test
...
...
@@ -156,8 +161,9 @@ public class RequestResponseBodyMethodProcessorTests {
replay
(
messageConverter
);
processor
.
handleReturnValue
(
returnValue
,
stringReturnValue
,
null
,
webRequest
);
processor
.
handleReturnValue
(
returnValue
,
stringReturnValue
,
mavContainer
,
webRequest
);
assertFalse
(
mavContainer
.
isResolveView
());
verify
(
messageConverter
);
}
...
...
@@ -173,8 +179,9 @@ public class RequestResponseBodyMethodProcessorTests {
replay
(
messageConverter
);
processor
.
handleReturnValue
(
returnValue
,
stringReturnValue
,
null
,
webRequest
);
processor
.
handleReturnValue
(
returnValue
,
stringReturnValue
,
mavContainer
,
webRequest
);
assertFalse
(
mavContainer
.
isResolveView
());
verify
(
messageConverter
);
}
...
...
org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/method/annotation/support/ServletResponseMethodArgumentResolverTests.java
浏览文件 @
6fe0ff9e
...
...
@@ -28,6 +28,7 @@ import org.springframework.core.MethodParameter;
import
org.springframework.mock.web.MockHttpServletRequest
;
import
org.springframework.mock.web.MockHttpServletResponse
;
import
org.springframework.web.context.request.ServletWebRequest
;
import
org.springframework.web.method.support.ModelAndViewContainer
;
import
org.springframework.web.servlet.mvc.method.annotation.support.ServletResponseMethodArgumentResolver
;
import
static
org
.
junit
.
Assert
.*;
...
...
@@ -45,12 +46,14 @@ public class ServletResponseMethodArgumentResolverTests {
private
MockHttpServletResponse
servletResponse
;
private
ModelAndViewContainer
mavContainer
;
@Before
public
void
setUp
()
throws
Exception
{
resolver
=
new
ServletResponseMethodArgumentResolver
();
supportedParams
=
getClass
().
getMethod
(
"supportedParams"
,
ServletResponse
.
class
,
OutputStream
.
class
,
Writer
.
class
);
supportedParams
=
getClass
().
getMethod
(
"supportedParams"
,
ServletResponse
.
class
,
OutputStream
.
class
,
Writer
.
class
);
servletResponse
=
new
MockHttpServletResponse
();
mavContainer
=
new
ModelAndViewContainer
();
webRequest
=
new
ServletWebRequest
(
new
MockHttpServletRequest
(),
servletResponse
);
}
...
...
@@ -65,8 +68,9 @@ public class ServletResponseMethodArgumentResolverTests {
assertTrue
(
"ServletResponse not supported"
,
resolver
.
supportsParameter
(
servletResponseParameter
));
Object
result
=
resolver
.
resolveArgument
(
servletResponseParameter
,
null
,
webRequest
,
null
);
Object
result
=
resolver
.
resolveArgument
(
servletResponseParameter
,
mavContainer
,
webRequest
,
null
);
assertSame
(
"Invalid result"
,
servletResponse
,
result
);
assertFalse
(
mavContainer
.
isResolveView
());
}
@Test
...
...
@@ -75,8 +79,9 @@ public class ServletResponseMethodArgumentResolverTests {
assertTrue
(
"OutputStream not supported"
,
resolver
.
supportsParameter
(
outputStreamParameter
));
Object
result
=
resolver
.
resolveArgument
(
outputStreamParameter
,
null
,
webRequest
,
null
);
Object
result
=
resolver
.
resolveArgument
(
outputStreamParameter
,
mavContainer
,
webRequest
,
null
);
assertSame
(
"Invalid result"
,
servletResponse
.
getOutputStream
(),
result
);
assertFalse
(
mavContainer
.
isResolveView
());
}
@Test
...
...
@@ -85,8 +90,9 @@ public class ServletResponseMethodArgumentResolverTests {
assertTrue
(
"Writer not supported"
,
resolver
.
supportsParameter
(
writerParameter
));
Object
result
=
resolver
.
resolveArgument
(
writerParameter
,
null
,
webRequest
,
null
);
Object
result
=
resolver
.
resolveArgument
(
writerParameter
,
mavContainer
,
webRequest
,
null
);
assertSame
(
"Invalid result"
,
servletResponse
.
getWriter
(),
result
);
assertFalse
(
mavContainer
.
isResolveView
());
}
public
void
supportedParams
(
ServletResponse
p0
,
OutputStream
p1
,
Writer
p2
)
{
...
...
org.springframework.web/.settings/org.eclipse.jdt.core.prefs
浏览文件 @
6fe0ff9e
此差异已折叠。
点击以展开。
org.springframework.web/.settings/org.eclipse.jdt.ui.prefs
浏览文件 @
6fe0ff9e
#Thu
Dec 18 06:36:28 PST 2008
#Thu
Apr 07 14:34:33 BST 2011
eclipse.preferences.version=1
formatter_profile=org.eclipse.jdt.ui.default.eclipse_profile
formatter_settings_version=11
org.springframework.web/src/main/java/org/springframework/web/method/HandlerMethod.java
浏览文件 @
6fe0ff9e
...
...
@@ -44,7 +44,7 @@ import org.springframework.util.ClassUtils;
public
class
HandlerMethod
{
/** Logger that is available to subclasses */
protected
final
Log
logger
=
LogFactory
.
getLog
(
this
.
getClass
());
protected
final
Log
logger
=
LogFactory
.
getLog
(
getClass
());
private
final
Object
bean
;
...
...
org.springframework.web/src/main/java/org/springframework/web/method/HandlerMethodSelector.java
浏览文件 @
6fe0ff9e
...
...
@@ -29,7 +29,7 @@ import org.springframework.util.ReflectionUtils.MethodFilter;
/**
* Defines the algorithm for searching handler methods exhaustively including interfaces and parent
* classes while also dealing with parameterized methods a
nd interface and class-based
proxies.
* classes while also dealing with parameterized methods a
s well as interface and class-based
proxies.
*
* @author Rossen Stoyanchev
* @since 3.1
...
...
@@ -42,6 +42,7 @@ public abstract class HandlerMethodSelector {
*
* @param handlerType the handler type to search handler methods on
* @param handlerMethodFilter a {@link MethodFilter} to help recognize handler methods of interest
* @return the selected methods, or an empty set
*/
public
static
Set
<
Method
>
selectMethods
(
final
Class
<?>
handlerType
,
final
MethodFilter
handlerMethodFilter
)
{
final
Set
<
Method
>
handlerMethods
=
new
LinkedHashSet
<
Method
>();
...
...
org.springframework.web/src/main/java/org/springframework/web/method/annotation/InitBinderMethodDataBinderFactory.java
浏览文件 @
6fe0ff9e
...
...
@@ -29,8 +29,8 @@ import org.springframework.web.context.request.NativeWebRequest;
import
org.springframework.web.method.support.InvocableHandlerMethod
;
/**
* A specialization of {@link DefaultDataBinderFactory} that further initializes {@link WebDataBinder} instances
*
through the invocation one or more
{@link InitBinder} methods.
* A specialization of {@link DefaultDataBinderFactory} that further initializes {@link WebDataBinder} instances
*
by invoking
{@link InitBinder} methods.
*
* @author Rossen Stoyanchev
* @since 3.1
...
...
@@ -41,7 +41,7 @@ public class InitBinderMethodDataBinderFactory extends DefaultDataBinderFactory
/**
* Create an {@code InitBinderMethodDataBinderFactory} instance with the given {@link InitBinder} methods.
* @param initBinderMethods {@link InitBinder} methods to use
when initializing
new data binder instances
* @param initBinderMethods {@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
*/
public
InitBinderMethodDataBinderFactory
(
List
<
InvocableHandlerMethod
>
initBinderMethods
,
...
...
@@ -51,9 +51,9 @@ public class InitBinderMethodDataBinderFactory extends DefaultDataBinderFactory
}
/**
* Create a
new {@link WebDataBinder} for the given target object and initialize it through the invocation
*
of {@link InitBinder} methods. Only {@link InitBinder} annotations that don't specify attributes names
* an
d {@link InitBinder} annotations that contain
the target object name are invoked.
* 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
* an
{@link InitBinder} annotation value that matches
the target object name are invoked.
* @see InitBinder#value()
*/
@Override
...
...
@@ -76,4 +76,4 @@ public class InitBinderMethodDataBinderFactory extends DefaultDataBinderFactory
return
dataBinder
;
}
}
}
\ No newline at end of file
org.springframework.web/src/main/java/org/springframework/web/method/annotation/ModelFactory.java
浏览文件 @
6fe0ff9e
...
...
@@ -26,11 +26,9 @@ import org.springframework.beans.BeanUtils;
import
org.springframework.core.Conventions
;
import
org.springframework.core.GenericTypeResolver
;
import
org.springframework.core.MethodParameter
;
import
org.springframework.ui.ExtendedModelMap
;
import
org.springframework.ui.ModelMap
;
import
org.springframework.util.StringUtils
;
import
org.springframework.validation.BindingResult
;
import
org.springframework.validation.support.BindingAwareModelMap
;
import
org.springframework.web.HttpSessionRequiredException
;
import
org.springframework.web.bind.WebDataBinder
;
import
org.springframework.web.bind.annotation.ModelAttribute
;
...
...
@@ -40,17 +38,17 @@ import org.springframework.web.bind.support.WebDataBinderFactory;
import
org.springframework.web.context.request.NativeWebRequest
;
import
org.springframework.web.method.HandlerMethod
;
import
org.springframework.web.method.support.InvocableHandlerMethod
;
import
org.springframework.web.method.support.ModelAndViewContainer
;
/**
* Provides methods to create and update
the "implicit" model for a given request.
* Provides methods to create and update
a model in the context of a given request.
*
* <p>{@link #createModel(NativeWebRequest, HandlerMethod)} prepares a model for use with
* a {@link RequestMapping} method. The model is populated with handler session attributes as well
* as request attributes obtained by invoking model attribute methods.
* <p>{@link #initModel(NativeWebRequest, ModelAndViewContainer, HandlerMethod)} populates the model
* with handler session attributes and attributes from model attribute methods.
*
* <p>{@link #update
Attributes(NativeWebRequest, SessionStatus, ModelMap, ModelMap
)} updates
* the model
used for the invocation of a {@link RequestMapping} method, adding handler session
*
attributes and {@link BindingResult} structur
es as necessary.
* <p>{@link #update
Model(NativeWebRequest, ModelAndViewContainer, SessionStatus
)} updates
* the model
(usually after the {@link RequestMapping} method has been called) promoting attributes
*
to the session and adding {@link BindingResult} attribut
es as necessary.
*
* @author Rossen Stoyanchev
* @since 3.1
...
...
@@ -66,8 +64,8 @@ public final class ModelFactory {
/**
* Create a ModelFactory instance with the provided {@link ModelAttribute} methods.
* @param attributeMethods {@link ModelAttribute}-annotated methods to invoke when populating a model
* @param binderFactory the binder factory to use
to add {@link BindingResult} instance
s to the model
* @param sessionHandler a session attributes handler to synch attributes
in the model
with the session
* @param binderFactory the binder factory to use
when adding {@link BindingResult}
s to the model
* @param sessionHandler a session attributes handler to synch attributes with the session
*/
public
ModelFactory
(
List
<
InvocableHandlerMethod
>
attributeMethods
,
WebDataBinderFactory
binderFactory
,
...
...
@@ -78,58 +76,78 @@ public final class ModelFactory {
}
/**
* P
repare a model for the current request obtaining attributes
in the following order:
* P
opulate the model for a request with attributes obtained
in the following order:
* <ol>
* <li>
Retrieve previously accessed handler session attributes from the session
* <li>
Add known (i.e. previously accessed) handler session attributes
* <li>Invoke model attribute methods
* <li>
Find request-handling method {@link ModelAttribute}-annotated arguments that are handler session attributes
* <li>
Check if any {@link ModelAttribute}-annotated arguments need to be added from the session
* </ol>
* <p>As a general rule a model attribute is added only once following the above order.
* <p>As a general rule model attributes are added only once.
*
* @param request the current request
* @param mavContainer the {@link ModelAndViewContainer} to add model attributes to
* @param requestMethod the request handling method for which the model is needed
* @return the created model
* @throws Exception if an exception occurs while invoking model attribute methods
*/
public
ModelMap
createModel
(
NativeWebRequest
request
,
HandlerMethod
requestMethod
)
throws
Exception
{
ExtendedModelMap
model
=
new
BindingAwareModelMap
();
Map
<
String
,
?>
sessionAttributes
=
this
.
sessionHandler
.
retrieveHandlerSessionAttributes
(
request
);
model
.
addAllAttributes
(
sessionAttributes
);
public
void
initModel
(
NativeWebRequest
request
,
ModelAndViewContainer
mavContainer
,
HandlerMethod
requestMethod
)
throws
Exception
{
invokeAttributeMethods
(
request
,
model
);
Map
<
String
,
?>
sessionAttributes
=
this
.
sessionHandler
.
retrieveHandlerSessionAttributes
(
request
);
mavContainer
.
addAllAttributes
(
sessionAttributes
);
addSessionAttributesByName
(
request
,
requestMethod
,
model
);
invokeAttributeMethods
(
request
,
mavContainer
);
return
model
;
addSessionAttributesByName
(
request
,
mavContainer
,
requestMethod
)
;
}
/**
*
Populate the model by invoking model attribute methods. If two methods provide the same attribute,
*
the attribute produced by the first method is us
ed.
*
Invoke model attribute methods to populate the model.
*
If two methods return the same attribute, the attribute from the first method is add
ed.
*/
private
void
invokeAttributeMethods
(
NativeWebRequest
request
,
ExtendedModelMap
model
)
throws
Exception
{
private
void
invokeAttributeMethods
(
NativeWebRequest
request
,
ModelAndViewContainer
mavContainer
)
throws
Exception
{
for
(
InvocableHandlerMethod
attrMethod
:
this
.
attributeMethods
)
{
String
modelName
=
attrMethod
.
getMethodAnnotation
(
ModelAttribute
.
class
).
value
();
if
(
StringUtils
.
hasText
(
modelName
)
&&
model
.
containsAttribute
(
modelName
))
{
if
(
mavContainer
.
containsAttribute
(
modelName
))
{
continue
;
}
Object
returnValue
=
attrMethod
.
invokeForRequest
(
request
,
m
odel
);
Object
returnValue
=
attrMethod
.
invokeForRequest
(
request
,
m
avContainer
);
if
(!
attrMethod
.
isVoid
()){
String
valueName
=
getNameForReturnValue
(
returnValue
,
attrMethod
.
getReturnType
());
if
(!
model
.
containsAttribute
(
valueName
))
{
model
.
addAttribute
(
valueName
,
returnValue
);
mavContainer
.
mergeAttribute
(
valueName
,
returnValue
);
}
}
}
/**
* Check if {@link ModelAttribute}-annotated arguments are handler session attributes and add them from the session.
*/
private
void
addSessionAttributesByName
(
NativeWebRequest
request
,
ModelAndViewContainer
mavContainer
,
HandlerMethod
requestMethod
)
{
for
(
MethodParameter
parameter
:
requestMethod
.
getMethodParameters
())
{
if
(
parameter
.
hasParameterAnnotation
(
ModelAttribute
.
class
))
{
continue
;
}
String
attrName
=
getNameForParameter
(
parameter
);
if
(!
mavContainer
.
containsAttribute
(
attrName
))
{
if
(
sessionHandler
.
isHandlerSessionAttribute
(
attrName
,
parameter
.
getParameterType
()))
{
Object
attrValue
=
sessionHandler
.
retrieveAttribute
(
request
,
attrName
);
if
(
attrValue
==
null
){
new
HttpSessionRequiredException
(
"Session attribute '"
+
attrName
+
"' not found in session"
);
}
mavContainer
.
addAttribute
(
attrName
,
attrValue
);
}
}
}
}
/**
* Derive the model
name for the given method
return value using one of the following:
* Derive the model
attribute name for the given
return value using one of the following:
* <ol>
* <li>The method {@link ModelAttribute} annotation value
* <li>The name of the return type
* <li>The name of the return type
* <li>The name of the return value type if the method return type is {@code Object}
* </ol>
* @param returnValue the value returned from a method invocation
...
...
@@ -149,29 +167,7 @@ public final class ModelFactory {
}
/**
* Find request-handling method, {@link ModelAttribute}-annotated arguments that are handler session attributes
* and add them to the model if not present.
*/
private
void
addSessionAttributesByName
(
NativeWebRequest
request
,
HandlerMethod
requestMethod
,
ModelMap
model
)
{
for
(
MethodParameter
parameter
:
requestMethod
.
getMethodParameters
())
{
if
(!
parameter
.
hasParameterAnnotation
(
ModelAttribute
.
class
))
{
continue
;
}
String
attrName
=
getNameForParameter
(
parameter
);
if
(!
model
.
containsKey
(
attrName
))
{
if
(
sessionHandler
.
isHandlerSessionAttribute
(
attrName
,
parameter
.
getParameterType
()))
{
Object
attrValue
=
sessionHandler
.
retrieveAttribute
(
request
,
attrName
);
if
(
attrValue
==
null
){
new
HttpSessionRequiredException
(
"Session attribute '"
+
attrName
+
"' not found in session"
);
}
model
.
addAttribute
(
attrName
,
attrValue
);
}
}
}
}
/**
* Derives the model name for the given method parameter using one of the following:
* Derives the model attribute name for the given method parameter using one of the following:
* <ol>
* <li>The parameter {@link ModelAttribute} annotation value
* <li>The name of the parameter type
...
...
@@ -185,33 +181,29 @@ public final class ModelFactory {
}
/**
*
Clean up handler session attributes when {@link SessionStatus#isComplete()} is {@code true}.
*
Promote model attributes to the session. Add
{@link BindingResult} attributes where missing.
*
Updates the model by cleaning handler session attributes depending on {@link SessionStatus#isComplete()},
*
promotes model attributes to the session, and adds
{@link BindingResult} attributes where missing.
* @param request the current request
* @param sessionStatus indicates whether handler session attributes are to be cleaned
* @param actualModel the model returned from the request method, or {@code null} when the response was handled
* @param implicitModel the model for the request
* @throws Exception if the process of creating {@link BindingResult} attributes causes a problem
* @param mavContainer the {@link ModelAndViewContainer} for the current request
* @param sessionStatus whether session processing is complete
* @throws Exception if the process of creating {@link BindingResult} attributes causes an error
*/
public
void
updateAttributes
(
NativeWebRequest
request
,
SessionStatus
sessionStatus
,
ModelMap
actualModel
,
ModelMap
implicitModel
)
throws
Exception
{
public
void
updateModel
(
NativeWebRequest
request
,
ModelAndViewContainer
mavContainer
,
SessionStatus
sessionStatus
)
throws
Exception
{
if
(
sessionStatus
.
isComplete
()){
this
.
sessionHandler
.
cleanupHandlerSessionAttributes
(
request
);
}
if
(
actualModel
!=
null
)
{
this
.
sessionHandler
.
storeHandlerSessionAttributes
(
request
,
actualModel
);
updateBindingResult
(
request
,
actualModel
);
this
.
sessionHandler
.
storeHandlerSessionAttributes
(
request
,
mavContainer
.
getModel
());
if
(
mavContainer
.
isResolveView
())
{
updateBindingResult
(
request
,
mavContainer
.
getModel
());
}
else
{
this
.
sessionHandler
.
storeHandlerSessionAttributes
(
request
,
implicitModel
);
}
}
/**
* Add {@link BindingResult}
structur
es to the model for attributes that require it.
* Add {@link BindingResult}
attribut
es to the model for attributes that require it.
*/
private
void
updateBindingResult
(
NativeWebRequest
request
,
ModelMap
model
)
throws
Exception
{
List
<
String
>
keyNames
=
new
ArrayList
<
String
>(
model
.
keySet
());
...
...
org.springframework.web/src/main/java/org/springframework/web/method/annotation/SessionAttributesHandler.java
浏览文件 @
6fe0ff9e
...
...
@@ -174,4 +174,5 @@ public class SessionAttributesHandler {
}
}
}
}
}
\ No newline at end of file
org.springframework.web/src/main/java/org/springframework/web/method/annotation/support/AbstractNamedValueMethodArgumentResolver.java
浏览文件 @
6fe0ff9e
...
...
@@ -25,13 +25,13 @@ import org.springframework.beans.factory.config.BeanExpressionContext;
import
org.springframework.beans.factory.config.BeanExpressionResolver
;
import
org.springframework.beans.factory.config.ConfigurableBeanFactory
;
import
org.springframework.core.MethodParameter
;
import
org.springframework.ui.ModelMap
;
import
org.springframework.web.bind.WebDataBinder
;
import
org.springframework.web.bind.annotation.ValueConstants
;
import
org.springframework.web.bind.support.WebDataBinderFactory
;
import
org.springframework.web.context.request.NativeWebRequest
;
import
org.springframework.web.context.request.RequestScope
;
import
org.springframework.web.method.support.HandlerMethodArgumentResolver
;
import
org.springframework.web.method.support.ModelAndViewContainer
;
/**
* Abstract base class for argument resolvers that resolve named values.
...
...
@@ -59,7 +59,7 @@ public abstract class AbstractNamedValueMethodArgumentResolver implements Handle
}
public
final
Object
resolveArgument
(
MethodParameter
parameter
,
Model
Map
model
,
Model
AndViewContainer
mavContainer
,
NativeWebRequest
webRequest
,
WebDataBinderFactory
binderFactory
)
throws
Exception
{
Class
<?>
paramType
=
parameter
.
getParameterType
();
...
...
org.springframework.web/src/main/java/org/springframework/web/method/annotation/support/ErrorsMethodArgumentResolver.java
浏览文件 @
6fe0ff9e
...
...
@@ -28,6 +28,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
import
org.springframework.web.bind.support.WebDataBinderFactory
;
import
org.springframework.web.context.request.NativeWebRequest
;
import
org.springframework.web.method.support.HandlerMethodArgumentResolver
;
import
org.springframework.web.method.support.ModelAndViewContainer
;
/**
* An implementation of {@link HandlerMethodArgumentResolver} that resolves {@link Errors} method parameters.
...
...
@@ -47,9 +48,10 @@ public class ErrorsMethodArgumentResolver implements HandlerMethodArgumentResolv
}
public
Object
resolveArgument
(
MethodParameter
parameter
,
Model
Map
model
,
Model
AndViewContainer
mavContainer
,
NativeWebRequest
webRequest
,
WebDataBinderFactory
binderFactory
)
throws
Exception
{
ModelMap
model
=
mavContainer
.
getModel
();
if
(
model
.
size
()
>
0
)
{
List
<
String
>
keys
=
new
ArrayList
<
String
>(
model
.
keySet
());
String
lastKey
=
keys
.
get
(
model
.
size
()-
1
);
...
...
org.springframework.web/src/main/java/org/springframework/web/method/annotation/support/ModelAttributeMethodProcessor.java
浏览文件 @
6fe0ff9e
...
...
@@ -20,13 +20,11 @@ import java.lang.annotation.Annotation;
import
org.springframework.beans.BeanUtils
;
import
org.springframework.core.MethodParameter
;
import
org.springframework.ui.ModelMap
;
import
org.springframework.validation.BindException
;
import
org.springframework.validation.DataBinder
;
import
org.springframework.validation.Errors
;
import
org.springframework.web.bind.WebDataBinder
;
import
org.springframework.web.bind.annotation.ModelAttribute
;
import
org.springframework.web.bind.support.SessionAttributeStore
;
import
org.springframework.web.bind.support.WebDataBinderFactory
;
import
org.springframework.web.bind.support.WebRequestDataBinder
;
import
org.springframework.web.context.request.NativeWebRequest
;
...
...
@@ -77,18 +75,16 @@ public class ModelAttributeMethodProcessor
}
/**
* Creates a {@link WebDataBinder} for the target model attribute and applies data binding to it.
* The model attribute may be obtained from the "implicit" model, from the session via, or by
* direct instantiation.
*
* @throws Exception if invoking an data binder initialization fails or if data binding and/or
* validation results in errors and the next method parameter is not of type {@link Errors}.
* Resolves the argument to a model attribute creating a {@link WebDataBinder} and invoking data binding on it.
* The model attribute is obtained from the model first or otherwise created via direct instantiation.
* @throws Exception if data binder initialization fails or if data binding results in errors and the next
* method parameter is not of type {@link Errors}.
*/
public
final
Object
resolveArgument
(
MethodParameter
parameter
,
Model
Map
model
,
Model
AndViewContainer
mavContainer
,
NativeWebRequest
webRequest
,
WebDataBinderFactory
binderFactory
)
throws
Exception
{
WebDataBinder
binder
=
createDataBinder
(
parameter
,
m
odel
,
webRequest
,
binderFactory
);
WebDataBinder
binder
=
createDataBinder
(
parameter
,
m
avContainer
,
webRequest
,
binderFactory
);
if
(
binder
.
getTarget
()
!=
null
)
{
doBind
(
binder
,
webRequest
);
...
...
@@ -102,24 +98,23 @@ public class ModelAttributeMethodProcessor
}
}
m
odel
.
putAll
(
binder
.
getBindingResult
().
getModel
());
m
avContainer
.
addAllAttributes
(
binder
.
getBindingResult
().
getModel
());
return
binder
.
getTarget
();
}
/**
* Creates a {@link WebDataBinder} for a target object which may be obtained from the "implicit" model,
* the session via {@link SessionAttributeStore}, or by direct instantiation.
* Creates a {@link WebDataBinder} for a target object.
*/
private
WebDataBinder
createDataBinder
(
MethodParameter
parameter
,
Model
Map
model
,
Model
AndViewContainer
mavContainer
,
NativeWebRequest
webRequest
,
WebDataBinderFactory
binderFactory
)
throws
Exception
{
String
attrName
=
ModelFactory
.
getNameForParameter
(
parameter
);
Object
target
;
if
(
m
odel
.
containsKey
(
attrName
))
{
target
=
m
odel
.
get
(
attrName
);
if
(
m
avContainer
.
containsAttribute
(
attrName
))
{
target
=
m
avContainer
.
getAttribute
(
attrName
);
}
else
{
target
=
BeanUtils
.
instantiateClass
(
parameter
.
getParameterType
());
...
...
@@ -166,7 +161,7 @@ public class ModelAttributeMethodProcessor
NativeWebRequest
webRequest
)
throws
Exception
{
if
(
returnValue
!=
null
)
{
String
name
=
ModelFactory
.
getNameForReturnValue
(
returnValue
,
returnType
);
mavContainer
.
add
Model
Attribute
(
name
,
returnValue
);
mavContainer
.
addAttribute
(
name
,
returnValue
);
}
}
...
...
org.springframework.web/src/main/java/org/springframework/web/method/annotation/support/ModelMethodProcessor.java
浏览文件 @
6fe0ff9e
...
...
@@ -20,7 +20,6 @@ import java.util.Map;
import
org.springframework.core.MethodParameter
;
import
org.springframework.ui.Model
;
import
org.springframework.ui.ModelMap
;
import
org.springframework.web.bind.annotation.ModelAttribute
;
import
org.springframework.web.bind.support.WebDataBinderFactory
;
import
org.springframework.web.context.request.NativeWebRequest
;
...
...
@@ -46,19 +45,10 @@ public class ModelMethodProcessor implements HandlerMethodArgumentResolver, Hand
}
public
Object
resolveArgument
(
MethodParameter
parameter
,
Model
Map
model
,
Model
AndViewContainer
mavContainer
,
NativeWebRequest
webRequest
,
WebDataBinderFactory
binderFactory
)
throws
Exception
{
Class
<?>
paramType
=
parameter
.
getParameterType
();
if
(
Model
.
class
.
isAssignableFrom
(
paramType
))
{
return
model
;
}
else
if
(
Map
.
class
.
isAssignableFrom
(
paramType
))
{
return
model
;
}
// should not happen
throw
new
UnsupportedOperationException
();
return
mavContainer
.
getModel
();
}
public
boolean
supportsReturnType
(
MethodParameter
returnType
)
{
...
...
@@ -78,10 +68,10 @@ public class ModelMethodProcessor implements HandlerMethodArgumentResolver, Hand
return
;
}
if
(
returnValue
instanceof
Model
)
{
mavContainer
.
add
ModelAttributes
((
Model
)
returnValue
);
mavContainer
.
add
AllAttributes
(((
Model
)
returnValue
).
asMap
()
);
}
else
if
(
returnValue
instanceof
Map
){
mavContainer
.
add
Mode
lAttributes
((
Map
)
returnValue
);
mavContainer
.
add
Al
lAttributes
((
Map
)
returnValue
);
}
else
{
// should not happen
...
...
org.springframework.web/src/main/java/org/springframework/web/method/annotation/support/RequestHeaderMapMethodArgumentResolver.java
浏览文件 @
6fe0ff9e
...
...
@@ -22,13 +22,13 @@ import java.util.Map;
import
org.springframework.core.MethodParameter
;
import
org.springframework.http.HttpHeaders
;
import
org.springframework.ui.ModelMap
;
import
org.springframework.util.LinkedMultiValueMap
;
import
org.springframework.util.MultiValueMap
;
import
org.springframework.web.bind.annotation.RequestHeader
;
import
org.springframework.web.bind.support.WebDataBinderFactory
;
import
org.springframework.web.context.request.NativeWebRequest
;
import
org.springframework.web.method.support.HandlerMethodArgumentResolver
;
import
org.springframework.web.method.support.ModelAndViewContainer
;
/**
* Implementation of {@link HandlerMethodArgumentResolver} that supports {@link Map} arguments annotated with
...
...
@@ -48,8 +48,8 @@ public class RequestHeaderMapMethodArgumentResolver implements HandlerMethodArgu
}
public
Object
resolveArgument
(
MethodParameter
parameter
,
Model
Map
model
,
NativeWebRequest
webRequest
,
Model
AndViewContainer
mavContainer
,
NativeWebRequest
webRequest
,
WebDataBinderFactory
binderFactory
)
throws
Exception
{
Class
<?>
paramType
=
parameter
.
getParameterType
();
...
...
org.springframework.web/src/main/java/org/springframework/web/method/annotation/support/RequestParamMapMethodArgumentResolver.java
浏览文件 @
6fe0ff9e
...
...
@@ -20,7 +20,6 @@ import java.util.LinkedHashMap;
import
java.util.Map
;
import
org.springframework.core.MethodParameter
;
import
org.springframework.ui.ModelMap
;
import
org.springframework.util.LinkedMultiValueMap
;
import
org.springframework.util.MultiValueMap
;
import
org.springframework.util.StringUtils
;
...
...
@@ -28,6 +27,7 @@ import org.springframework.web.bind.annotation.RequestParam;
import
org.springframework.web.bind.support.WebDataBinderFactory
;
import
org.springframework.web.context.request.NativeWebRequest
;
import
org.springframework.web.method.support.HandlerMethodArgumentResolver
;
import
org.springframework.web.method.support.ModelAndViewContainer
;
/**
* Implementation of {@link HandlerMethodArgumentResolver} that supports {@link Map} arguments annotated with
...
...
@@ -52,7 +52,7 @@ public class RequestParamMapMethodArgumentResolver implements HandlerMethodArgum
}
public
Object
resolveArgument
(
MethodParameter
parameter
,
Model
Map
model
,
Model
AndViewContainer
mavContainer
,
NativeWebRequest
webRequest
,
WebDataBinderFactory
binderFactory
)
throws
Exception
{
Class
<?>
paramType
=
parameter
.
getParameterType
();
...
...
org.springframework.web/src/main/java/org/springframework/web/method/annotation/support/WebArgumentResolverAdapter.java
浏览文件 @
6fe0ff9e
...
...
@@ -19,7 +19,6 @@ package org.springframework.web.method.annotation.support;
import
org.apache.commons.logging.Log
;
import
org.apache.commons.logging.LogFactory
;
import
org.springframework.core.MethodParameter
;
import
org.springframework.ui.ModelMap
;
import
org.springframework.util.Assert
;
import
org.springframework.util.ClassUtils
;
import
org.springframework.web.bind.support.WebArgumentResolver
;
...
...
@@ -28,6 +27,7 @@ import org.springframework.web.context.request.NativeWebRequest;
import
org.springframework.web.context.request.RequestAttributes
;
import
org.springframework.web.context.request.RequestContextHolder
;
import
org.springframework.web.method.support.HandlerMethodArgumentResolver
;
import
org.springframework.web.method.support.ModelAndViewContainer
;
/**
* Adapts a {@link WebArgumentResolver} into the {@link HandlerMethodArgumentResolver} contract.
...
...
@@ -75,7 +75,7 @@ public class WebArgumentResolverAdapter implements HandlerMethodArgumentResolver
}
public
Object
resolveArgument
(
MethodParameter
parameter
,
Model
Map
model
,
Model
AndViewContainer
mavContainer
,
NativeWebRequest
webRequest
,
WebDataBinderFactory
binderFactory
)
throws
Exception
{
Class
<?>
paramType
=
parameter
.
getParameterType
();
...
...
org.springframework.web/src/main/java/org/springframework/web/method/support/HandlerMethodArgumentResolver.java
浏览文件 @
6fe0ff9e
...
...
@@ -17,21 +17,20 @@
package
org.springframework.web.method.support
;
import
org.springframework.core.MethodParameter
;
import
org.springframework.ui.ModelMap
;
import
org.springframework.web.bind.WebDataBinder
;
import
org.springframework.web.bind.support.WebDataBinderFactory
;
import
org.springframework.web.context.request.NativeWebRequest
;
/**
* Strategy interface for resolving method parameters into argument values
from
a given request.
* Strategy interface for resolving method parameters into argument values
in the context of
a given request.
*
* @author Arjen Poutsma
* @since 3.1
*/
public
interface
HandlerMethodArgumentResolver
extends
HandlerMethodProcessor
{
public
interface
HandlerMethodArgumentResolver
{
/**
*
Indicates w
hether the given {@linkplain MethodParameter method parameter} is supported by this resolver.
*
W
hether the given {@linkplain MethodParameter method parameter} is supported by this resolver.
*
* @param parameter the method parameter to check
* @return {@code true} if this resolver supports the supplied parameter; {@code false} otherwise
...
...
@@ -39,20 +38,20 @@ public interface HandlerMethodArgumentResolver extends HandlerMethodProcessor {
boolean
supportsParameter
(
MethodParameter
parameter
);
/**
* Resolves a method parameter into an argument value from a given request
and a {@link ModelMap} providing
*
the ability to both access and add new model attributes. A {@link WebDataBinderFactory} is also provided
*
for creating a {@link WebDataBinder} instance to use for data binding and type conversion
.
* Resolves a method parameter into an argument value from a given request
. A {@link ModelAndViewContainer}
*
provides access to the model for the request. A {@link WebDataBinderFactory} provides a way to create
*
a {@link WebDataBinder} instance when needed for data binding and type conversion purposes
.
*
* @param parameter the
parameter to resolve to an argument
. This parameter must have previously been passed to
* @param parameter the
method parameter to resolve
. This parameter must have previously been passed to
* {@link #supportsParameter(org.springframework.core.MethodParameter)} and it must have returned {@code true}
* @param m
odel the model
for the current request
* @param webRequest the current request
.
* @param binderFactory a factory
in case the resolver needs to create a {@link WebDataBinder} instance
* @param m
avContainer the {@link ModelAndViewContainer}
for the current request
* @param webRequest the current request
* @param binderFactory a factory
for creating {@link WebDataBinder} instances
* @return the resolved argument value, or {@code null}.
* @throws Exception in case of errors with the preparation of argument values
*/
Object
resolveArgument
(
MethodParameter
parameter
,
Model
Map
model
,
Model
AndViewContainer
mavContainer
,
NativeWebRequest
webRequest
,
WebDataBinderFactory
binderFactory
)
throws
Exception
;
...
...
org.springframework.web/src/main/java/org/springframework/web/method/support/HandlerMethodArgumentResolverComposite.java
浏览文件 @
6fe0ff9e
...
...
@@ -24,22 +24,19 @@ import java.util.concurrent.ConcurrentHashMap;
import
org.apache.commons.logging.Log
;
import
org.apache.commons.logging.LogFactory
;
import
org.springframework.core.MethodParameter
;
import
org.springframework.ui.ModelMap
;
import
org.springframework.web.bind.support.WebDataBinderFactory
;
import
org.springframework.web.context.request.NativeWebRequest
;
/**
* Implementation of {@link HandlerMethodArgumentResolver} that resolves handler method arguments by delegating
* to a list of registered {@link HandlerMethodArgumentResolver}s.
*
* <p>Previously resolved method argument types are cached internally for faster lookups.
* Resolves method parameters by delegating to a list of registered {@link HandlerMethodArgumentResolver}s.
* Previously resolved method parameters are cached for faster lookups.
*
* @author Rossen Stoyanchev
* @since 3.1
*/
public
class
HandlerMethodArgumentResolverComposite
implements
HandlerMethodArgumentResolver
{
protected
final
Log
logger
=
LogFactory
.
getLog
(
HandlerMethodArgumentResolverComposite
.
class
);
protected
final
Log
logger
=
LogFactory
.
getLog
(
getClass
()
);
private
final
List
<
HandlerMethodArgumentResolver
>
argumentResolvers
=
new
ArrayList
<
HandlerMethodArgumentResolver
>();
...
...
@@ -48,34 +45,34 @@ public class HandlerMethodArgumentResolverComposite implements HandlerMethodArgu
new
ConcurrentHashMap
<
MethodParameter
,
HandlerMethodArgumentResolver
>();
/**
*
Indicates whether the given {@linkplain MethodParameter method parameter} is supported by any of the
*
registered {@link HandlerMethodArgumentResolver}s
.
*
Whether the given {@linkplain MethodParameter method parameter} is supported by any registered
*
{@link HandlerMethodArgumentResolver}
.
*/
public
boolean
supportsParameter
(
MethodParameter
parameter
)
{
return
getArgumentResolver
(
parameter
)
!=
null
;
}
/**
*
Resolve a method parameter into an argument value for the given request by iterating over registered
*
{@link HandlerMethodArgumentResolver}s to find one that supports the given method parameter
.
*
Iterate over registered {@link HandlerMethodArgumentResolver}s and invoke the one that supports it.
*
@exception IllegalStateException if no suitable {@link HandlerMethodArgumentResolver} is found
.
*/
public
Object
resolveArgument
(
MethodParameter
parameter
,
Model
Map
model
,
Model
AndViewContainer
mavContainer
,
NativeWebRequest
webRequest
,
WebDataBinderFactory
binderFactory
)
throws
Exception
{
HandlerMethodArgumentResolver
resolver
=
getArgumentResolver
(
parameter
);
if
(
resolver
!=
null
)
{
return
resolver
.
resolveArgument
(
parameter
,
model
,
webRequest
,
binderFactory
);
return
resolver
.
resolveArgument
(
parameter
,
mavContainer
,
webRequest
,
binderFactory
);
}
else
{
throw
new
IllegalStateException
(
"No suitable HandlerMethodArgumentResolver found. "
+
"supportsParameter(MethodParameter) should have been called previously."
);
}
throw
new
IllegalStateException
(
"No suitable HandlerMethodArgumentResolver found. "
+
"supportsParameter(MethodParameter) should have been called previously."
);
}
/**
* Find a registered {@link HandlerMethodArgumentResolver} that supports the given method parameter.
* @return a {@link HandlerMethodArgumentResolver} instance, or {@code null} if none
*/
private
HandlerMethodArgumentResolver
getArgumentResolver
(
MethodParameter
parameter
)
{
HandlerMethodArgumentResolver
result
=
this
.
argumentResolverCache
.
get
(
parameter
);
...
...
@@ -94,15 +91,6 @@ public class HandlerMethodArgumentResolverComposite implements HandlerMethodArgu
}
return
result
;
}
/**
* Indicates whether the argument resolver that supports the given method parameter uses the response argument.
* @see HandlerMethodProcessor#usesResponseArgument(MethodParameter)
*/
public
boolean
usesResponseArgument
(
MethodParameter
parameter
)
{
HandlerMethodArgumentResolver
resolver
=
getArgumentResolver
(
parameter
);
return
(
resolver
!=
null
&&
resolver
.
usesResponseArgument
(
parameter
));
}
/**
* Register the given {@link HandlerMethodArgumentResolver}.
...
...
org.springframework.web/src/main/java/org/springframework/web/method/support/HandlerMethodProcessor.java
已删除
100644 → 0
浏览文件 @
3d8b476f
/*
* Copyright 2002-2011 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
org.springframework.web.method.support
;
import
org.springframework.core.MethodParameter
;
/**
* A base interface for {@link HandlerMethodArgumentResolver}s and {@link HandlerMethodReturnValueHandler}s.
*
* @author Arjen Poutsma
* @since 3.1
*/
public
interface
HandlerMethodProcessor
{
/**
* Indicates whether the given {@linkplain org.springframework.core.MethodParameter method parameter},
* uses the response argument with the implication that the response will be handled directly by invoking
* the method and will not require view name resolution followed by rendering.
*
* @param parameter the method parameter, either a method argument or a return type
* @return {@code true} if the supplied parameter uses the response argument; {@code false} otherwise
*/
boolean
usesResponseArgument
(
MethodParameter
parameter
);
}
\ No newline at end of file
org.springframework.web/src/main/java/org/springframework/web/method/support/HandlerMethodReturnValueHandler.java
浏览文件 @
6fe0ff9e
...
...
@@ -20,15 +20,15 @@ import org.springframework.core.MethodParameter;
import
org.springframework.web.context.request.NativeWebRequest
;
/**
* Strategy interface to
process the value returned from a handler method invocation
.
* Strategy interface to
handle the value returned from the invocation of a handler method
.
*
* @author Arjen Poutsma
* @since 3.1
*/
public
interface
HandlerMethodReturnValueHandler
extends
HandlerMethodProcessor
{
public
interface
HandlerMethodReturnValueHandler
{
/**
*
Indicates w
hether the given {@linkplain MethodParameter method return type} is supported by this handler.
*
W
hether the given {@linkplain MethodParameter method return type} is supported by this handler.
*
* @param returnType the method return type to check
* @return {@code true} if this handler supports the supplied return type; {@code false} otherwise
...
...
@@ -36,15 +36,18 @@ public interface HandlerMethodReturnValueHandler extends HandlerMethodProcessor
boolean
supportsReturnType
(
MethodParameter
returnType
);
/**
* Handles the given value returned by a handler method invocation by writing directly to the response
* or by using the {@code mavContainer} argument to add model attributes and/or set the view.
* Handle the given return value by adding attributes to the model, setting the view (or view name),
* or by writing to the response. {@link HandlerMethodReturnValueHandler} implementations should also
* consider whether to set {@link ModelAndViewContainer#setResolveView(boolean)}, which is set to
* {@code true} by default and therefore needs to be set to {@code false} explicitly if view
* resolution is to be bypassed.
*
* @param returnValue the
return value to handle
* @param returnType the
return type to handl
e. This type must have previously been passed to
* @param returnValue the
value returned from the handler method
* @param returnType the
type of the return valu
e. This type must have previously been passed to
* {@link #supportsReturnType(org.springframework.core.MethodParameter)} and it must have returned {@code true}
* @param mavContainer
records model and view choices
* @param mavContainer
the {@link ModelAndViewContainer} for the current request
* @param webRequest the current request
* @throws Exception i
n case of errors
* @throws Exception i
f the return value handling results in an error
*/
void
handleReturnValue
(
Object
returnValue
,
MethodParameter
returnType
,
...
...
org.springframework.web/src/main/java/org/springframework/web/method/support/HandlerMethodReturnValueHandlerComposite.java
浏览文件 @
6fe0ff9e
...
...
@@ -27,17 +27,15 @@ import org.springframework.core.MethodParameter;
import
org.springframework.web.context.request.NativeWebRequest
;
/**
* Implementation of {@link HandlerMethodReturnValueHandler} that handles method return values by
* delegating to a list of registered {@link HandlerMethodReturnValueHandler}s.
*
* <p>Previously resolved return types are cached internally for faster lookups.
* Handles method return values by delegating to a list of registered {@link HandlerMethodReturnValueHandler}s.
* Previously resolved return types are cached for faster lookups.
*
* @author Rossen Stoyanchev
* @since 3.1
*/
public
class
HandlerMethodReturnValueHandlerComposite
implements
HandlerMethodReturnValueHandler
{
protected
final
Log
logger
=
LogFactory
.
getLog
(
HandlerMethodArgumentResolverComposite
.
class
);
protected
final
Log
logger
=
LogFactory
.
getLog
(
getClass
()
);
private
final
List
<
HandlerMethodReturnValueHandler
>
returnValueHandlers
=
new
ArrayList
<
HandlerMethodReturnValueHandler
>();
...
...
@@ -46,16 +44,16 @@ public class HandlerMethodReturnValueHandlerComposite implements HandlerMethodRe
new
ConcurrentHashMap
<
MethodParameter
,
HandlerMethodReturnValueHandler
>();
/**
*
Indicates whether the given {@linkplain MethodParameter method return type} is supported by any of the
*
registered {@link HandlerMethodReturnValueHandler}s
.
*
Whether the given {@linkplain MethodParameter method return type} is supported by any registered
*
{@link HandlerMethodReturnValueHandler}
.
*/
public
boolean
supportsReturnType
(
MethodParameter
returnType
)
{
return
getReturnValueHandler
(
returnType
)
!=
null
;
}
/**
*
Handles the given method return value by iterating over registered {@link HandlerMethodReturnValueHandler}s
*
to find one that supports it
.
*
Iterate over registered {@link HandlerMethodReturnValueHandler}s and invoke the one that supports it.
*
@exception IllegalStateException if no suitable {@link HandlerMethodReturnValueHandler} is found
.
*/
public
void
handleReturnValue
(
Object
returnValue
,
MethodParameter
returnType
,
...
...
@@ -64,31 +62,28 @@ public class HandlerMethodReturnValueHandlerComposite implements HandlerMethodRe
HandlerMethodReturnValueHandler
handler
=
getReturnValueHandler
(
returnType
);
if
(
handler
!=
null
)
{
handler
.
handleReturnValue
(
returnValue
,
returnType
,
mavContainer
,
webRequest
);
return
;
}
throw
new
IllegalStateException
(
"No suitable HandlerMethodReturnValueHandler found. "
+
"supportsReturnType(MethodParameter) should have been called previously"
);
else
{
throw
new
IllegalStateException
(
"No suitable HandlerMethodReturnValueHandler found. "
+
"supportsReturnType(MethodParameter) should have been called previously"
);
}
}
/**
* Find a registered {@link HandlerMethodReturnValueHandler} that supports the given
method
return type.
* Find a registered {@link HandlerMethodReturnValueHandler} that supports the given return type.
*/
private
HandlerMethodReturnValueHandler
getReturnValueHandler
(
MethodParameter
returnType
)
{
if
(
this
.
returnValueHandlers
==
null
)
{
return
null
;
}
HandlerMethodReturnValueHandler
result
=
this
.
returnValueHandlerCache
.
get
(
returnType
);
if
(
result
==
null
)
{
for
(
HandlerMethodReturnValueHandler
methodR
eturnValueHandler
:
returnValueHandlers
)
{
for
(
HandlerMethodReturnValueHandler
r
eturnValueHandler
:
returnValueHandlers
)
{
if
(
logger
.
isTraceEnabled
())
{
logger
.
trace
(
"Testing if return value handler ["
+
methodR
eturnValueHandler
+
"] supports ["
+
logger
.
trace
(
"Testing if return value handler ["
+
r
eturnValueHandler
+
"] supports ["
+
returnType
.
getGenericParameterType
()
+
"]"
);
}
if
(
methodR
eturnValueHandler
.
supportsReturnType
(
returnType
))
{
result
=
methodR
eturnValueHandler
;
this
.
returnValueHandlerCache
.
put
(
returnType
,
methodR
eturnValueHandler
);
if
(
r
eturnValueHandler
.
supportsReturnType
(
returnType
))
{
result
=
r
eturnValueHandler
;
this
.
returnValueHandlerCache
.
put
(
returnType
,
r
eturnValueHandler
);
break
;
}
}
...
...
@@ -96,15 +91,6 @@ public class HandlerMethodReturnValueHandlerComposite implements HandlerMethodRe
return
result
;
}
/**
* Indicates whether the return value handler that supports the given method parameter uses the response.
* @see HandlerMethodProcessor#usesResponseArgument(MethodParameter)
*/
public
boolean
usesResponseArgument
(
MethodParameter
parameter
)
{
HandlerMethodReturnValueHandler
handler
=
getReturnValueHandler
(
parameter
);
return
(
handler
!=
null
&&
handler
.
usesResponseArgument
(
parameter
));
}
/**
* Register the given {@link HandlerMethodReturnValueHandler}.
*/
...
...
org.springframework.web/src/main/java/org/springframework/web/method/support/InvocableHandlerMethod.java
浏览文件 @
6fe0ff9e
...
...
@@ -24,7 +24,6 @@ import org.springframework.core.GenericTypeResolver;
import
org.springframework.core.LocalVariableTableParameterNameDiscoverer
;
import
org.springframework.core.MethodParameter
;
import
org.springframework.core.ParameterNameDiscoverer
;
import
org.springframework.ui.ModelMap
;
import
org.springframework.util.ReflectionUtils
;
import
org.springframework.web.bind.WebDataBinder
;
import
org.springframework.web.bind.support.SessionStatus
;
...
...
@@ -33,12 +32,15 @@ import org.springframework.web.context.request.NativeWebRequest;
import
org.springframework.web.method.HandlerMethod
;
/**
* Provides a
way to invoke a handler method after resolving its method argument values through
*
{@link HandlerMethodArgumentResolver}s in the context of the current request
.
* Provides a
method for invoking the handler method for a given request after resolving its method argument
*
values through registered {@link HandlerMethodArgumentResolver}s
.
*
* <p>Resolving argument values often requires a {@link WebDataBinder} for data binding and type conversion.
* Use {@link #setDataBinderFactory(WebDataBinderFactory)} to provide a factory for that. The list of argument
* resolvers can be set via {@link #setHandlerMethodArgumentResolvers(HandlerMethodArgumentResolverComposite)}.
* <p>Argument resolution often requires a {@link WebDataBinder} for data binding or for type conversion.
* Use the {@link #setDataBinderFactory(WebDataBinderFactory)} property to supply a binder factory to pass to
* argument resolvers.
*
* <p>Use {@link #setHandlerMethodArgumentResolvers(HandlerMethodArgumentResolverComposite)} to customize
* the list of argument resolvers.
*
* @author Rossen Stoyanchev
* @since 3.1
...
...
@@ -52,7 +54,7 @@ public class InvocableHandlerMethod extends HandlerMethod {
private
ParameterNameDiscoverer
parameterNameDiscoverer
=
new
LocalVariableTableParameterNameDiscoverer
();
/**
* Constructs a new
invocable
handler method with the given bean instance and method.
* Constructs a new handler method with the given bean instance and method.
* @param bean the bean instance
* @param method the method
*/
...
...
@@ -61,7 +63,7 @@ public class InvocableHandlerMethod extends HandlerMethod {
}
/**
* Constructs a new
invocable
handler method with the given bean instance, method name and parameters.
* Constructs a new handler method with the given bean instance, method name and parameters.
* @param bean the object bean
* @param methodName the method name
* @param parameterTypes the method parameter types
...
...
@@ -73,9 +75,8 @@ public class InvocableHandlerMethod extends HandlerMethod {
}
/**
* Sets the {@link WebDataBinderFactory} to be passed to argument resolvers that require a
* {@link WebDataBinder} to do type conversion or data binding on the method argument value.
*
* Sets the {@link WebDataBinderFactory} to be passed to argument resolvers allowing them to create
* a {@link WebDataBinder} for data binding and type conversion purposes.
* @param dataBinderFactory the data binder factory.
*/
public
void
setDataBinderFactory
(
WebDataBinderFactory
dataBinderFactory
)
{
...
...
@@ -90,30 +91,30 @@ public class InvocableHandlerMethod extends HandlerMethod {
}
/**
* Set the ParameterNameDiscoverer to use for resolving method parameter names if needed
* (e.g. for default attribute names).
* <p>Default is a {@link org.springframework.core.LocalVariableTableParameterNameDiscoverer}.
* Set the ParameterNameDiscoverer for resolving parameter names when needed (e.g. default request attribute name).
* <p>Default is an {@link org.springframework.core.LocalVariableTableParameterNameDiscoverer} instance.
*/
public
void
setParameterNameDiscoverer
(
ParameterNameDiscoverer
parameterNameDiscoverer
)
{
this
.
parameterNameDiscoverer
=
parameterNameDiscoverer
;
}
/**
* Invoke the method after resolving its argument values
based on the given request.
*
<p>Most argument values are resolved with the help of {@link HandlerMethodArgumentResolver}s
*
configured via {@link #setHandlerMethodArgumentResolvers(HandlerMethodArgumentResolverComposite)}
.
*
However, the {@code provideArgs} parameter can be used to supply argument values for use
*
directly rather than relying on argument resolution - e.g. {@link WebDataBinder},
*
{@link SessionStatus}, or the thrown exception in a HandlerExceptionResolver.
* Invoke the method after resolving its argument values
in the context of the given request. <p>Argument
*
values are commonly resolved through {@link HandlerMethodArgumentResolver}s. The {@code provideArgs}
*
parameter however may supply argument values to be used directly, i.e. without argument resolution
.
*
Examples of provided argument values include a {@link WebDataBinder}, a {@link SessionStatus}, or
*
a thrown exception instance. Provided argument values are checked before argument resolvers.
*
* @param request the current request
* @param m
odel the model used throughout
the current request
* @param providedArgs argument values to try to use
, thus bypassing argument
resolution
* @param m
avContainer the {@link ModelAndViewContainer} for
the current request
* @param providedArgs argument values to try to use
without view
resolution
* @return the raw value returned by the invoked method
* @exception Exception raised if no suitable argument resolver can be found, or the method raised an exception
*/
public
final
Object
invokeForRequest
(
NativeWebRequest
request
,
ModelMap
model
,
Object
...
providedArgs
)
throws
Exception
{
Object
[]
args
=
getMethodArgument
s
(
request
,
model
,
providedArgs
);
public
final
Object
invokeForRequest
(
NativeWebRequest
request
,
ModelAndViewContainer
mavContainer
,
Object
...
providedArgs
)
throws
Exception
{
Object
[]
args
=
getMethodArgument
Values
(
request
,
mavContainer
,
providedArgs
);
if
(
logger
.
isTraceEnabled
())
{
StringBuilder
builder
=
new
StringBuilder
(
"Invoking ["
);
...
...
@@ -131,8 +132,12 @@ public class InvocableHandlerMethod extends HandlerMethod {
return
returnValue
;
}
private
Object
[]
getMethodArguments
(
NativeWebRequest
request
,
ModelMap
model
,
Object
...
providedArgs
)
throws
Exception
{
/**
* Get the method argument values for the current request.
*/
private
Object
[]
getMethodArgumentValues
(
NativeWebRequest
request
,
ModelAndViewContainer
mavContainer
,
Object
...
providedArgs
)
throws
Exception
{
MethodParameter
[]
parameters
=
getMethodParameters
();
Object
[]
args
=
new
Object
[
parameters
.
length
];
for
(
int
i
=
0
;
i
<
parameters
.
length
;
i
++)
{
...
...
@@ -141,13 +146,11 @@ public class InvocableHandlerMethod extends HandlerMethod {
GenericTypeResolver
.
resolveParameterType
(
parameter
,
getBean
().
getClass
());
args
[
i
]
=
resolveProvidedArgument
(
parameter
,
providedArgs
);
if
(
args
[
i
]
!=
null
)
{
continue
;
}
if
(
this
.
argumentResolvers
.
supportsParameter
(
parameter
))
{
args
[
i
]
=
this
.
argumentResolvers
.
resolveArgument
(
parameter
,
m
odel
,
request
,
dataBinderFactory
);
args
[
i
]
=
this
.
argumentResolvers
.
resolveArgument
(
parameter
,
m
avContainer
,
request
,
dataBinderFactory
);
}
else
{
throw
new
IllegalStateException
(
"Cannot resolve argument index="
+
parameter
.
getParameterIndex
()
+
""
...
...
@@ -158,6 +161,9 @@ public class InvocableHandlerMethod extends HandlerMethod {
return
args
;
}
/**
* Attempt to resolve a method parameter from the list of provided argument values.
*/
private
Object
resolveProvidedArgument
(
MethodParameter
parameter
,
Object
...
providedArgs
)
{
if
(
providedArgs
==
null
)
{
return
null
;
...
...
@@ -171,10 +177,7 @@ public class InvocableHandlerMethod extends HandlerMethod {
}
/**
* Invokes this handler method with the given argument values.
* @param args the argument values
* @return the result of the invocation
* @throws Exception when the method invocation results in an exception
* Invoke this handler method with the given argument values.
*/
private
Object
invoke
(
Object
...
args
)
throws
Exception
{
ReflectionUtils
.
makeAccessible
(
this
.
getBridgedMethod
());
...
...
@@ -224,19 +227,5 @@ public class InvocableHandlerMethod extends HandlerMethod {
throw
(
Exception
)
targetException
;
}
}
/**
* Whether any of the registered {@link HandlerMethodArgumentResolver}s use the response argument.
* @see HandlerMethodProcessor#usesResponseArgument(MethodParameter)
*/
protected
boolean
usesResponseArgument
()
{
MethodParameter
[]
methodParameters
=
getMethodParameters
();
for
(
MethodParameter
methodParameter
:
methodParameters
)
{
if
(
this
.
argumentResolvers
.
usesResponseArgument
(
methodParameter
))
{
return
true
;
}
}
return
false
;
}
}
\ No newline at end of file
org.springframework.web/src/main/java/org/springframework/web/method/support/ModelAndViewContainer.java
浏览文件 @
6fe0ff9e
...
...
@@ -18,16 +18,21 @@ package org.springframework.web.method.support;
import
java.util.Map
;
import
org.springframework.ui.ExtendedModelMap
;
import
org.springframework.ui.Model
;
import
org.springframework.ui.ModelMap
;
import
org.springframework.util.Assert
;
import
org.springframework.util.StringUtils
;
import
org.springframework.validation.support.BindingAwareModelMap
;
/**
* Contains model and view choices made by {@link HandlerMethodReturnValueHandler}s.
* Provides access to the model and a place to record model and view related decisions to all
* {@link HandlerMethodArgumentResolver}s and {@link HandlerMethodReturnValueHandler}s .
*
* <p>Allows return value handlers to set only the bits that are relevant to them - i.e. model, view,
* or none, while also taking care of merging attributes added by the {@link HandlerMethodReturnValueHandler}
* with attributes from the implicit model.
* <p>In addition to storing model attributes and a view, the {@link ModelAndViewContainer} also provides
* a {@link #setResolveView(boolean)} flag, which can be used to request or bypass a view resolution phase.
* This is most commonly used from {@link HandlerMethodReturnValueHandler}s but in some cases may also be
* used from {@link HandlerMethodArgumentResolver}s such as when a handler method accepts an argument
* providing access to the response. When that is the case, if the handler method returns {@code null},
* view resolution is skipped.
*
* @author Rossen Stoyanchev
* @since 3.1
...
...
@@ -38,44 +43,117 @@ public class ModelAndViewContainer {
private
Object
view
;
private
final
ModelMap
actualModel
=
new
ExtendedModelMap
()
;
private
final
ModelMap
model
;
private
final
ModelMap
implicitModel
;
private
boolean
resolveView
=
true
;
public
ModelAndViewContainer
(
ModelMap
implicitModel
)
{
this
.
implicitModel
=
(
implicitModel
!=
null
)
?
implicitModel
:
new
ExtendedModelMap
();
/**
* Create a {@link ModelAndViewContainer} instance with a {@link BindingAwareModelMap}.
*/
public
ModelAndViewContainer
()
{
this
.
model
=
new
BindingAwareModelMap
();
}
/**
* Create a {@link ModelAndViewContainer} instance with the given {@link ModelMap} instance.
* @param model the model to use
*/
public
ModelAndViewContainer
(
ModelMap
model
)
{
Assert
.
notNull
(
model
);
this
.
model
=
model
;
}
/**
* @return the model for the current request
*/
public
ModelMap
getModel
()
{
return
new
ExtendedModelMap
().
addAllAttributes
(
actualModel
).
mergeAttributes
(
implicitModel
)
;
return
model
;
}
/**
* @return the view name to use for view resolution, or {@code null}
*/
public
String
getViewName
()
{
return
this
.
viewName
;
}
/**
* @param viewName the name of the view to use for view resolution
*/
public
void
setViewName
(
String
viewName
)
{
this
.
viewName
=
viewName
;
}
/**
* @return the view instance to use for view resolution
*/
public
Object
getView
()
{
return
this
.
view
;
}
/**
* @param view the view instance to use for view resolution
*/
public
void
setView
(
Object
view
)
{
this
.
view
=
view
;
}
/**
* @return whether the view resolution is requested ({@code true}), or should be bypassed ({@code false})
*/
public
boolean
isResolveView
()
{
return
resolveView
;
}
/**
* @param resolveView whether the view resolution is requested ({@code true}), or should be bypassed ({@code false})
*/
public
void
setResolveView
(
boolean
resolveView
)
{
this
.
resolveView
=
resolveView
;
}
public
void
addModelAttributes
(
Model
attributes
)
{
actualModel
.
addAllAttributes
(
attributes
.
asMap
());
/**
* Whether model contains an attribute of the given name.
* @param name the name of the model attribute
* @return {@code true} if the model contains an attribute by that name and the name is not an empty string
*/
public
boolean
containsAttribute
(
String
name
)
{
return
(
StringUtils
.
hasText
(
name
)
&&
model
.
containsAttribute
(
name
));
}
public
void
addModelAttributes
(
Map
<
String
,
Object
>
attributes
)
{
actualModel
.
addAllAttributes
(
attributes
);
/**
* @param name the attribute to get from the model
* @return the attribute or {@code null}
*/
public
Object
getAttribute
(
String
name
)
{
return
model
.
get
(
name
);
}
public
void
addModelAttribute
(
String
name
,
Object
value
)
{
actualModel
.
addAttribute
(
name
,
value
);
/**
* Add the supplied attribute under the given name.
* @param name the name of the model attribute (never null)
* @param value the model attribute value (can be null)
*/
public
void
addAttribute
(
String
name
,
Object
value
)
{
model
.
addAttribute
(
name
,
value
);
}
/**
* Copy all attributes in the supplied Map into the model
*/
public
void
addAllAttributes
(
Map
<
String
,
?>
attributes
)
{
model
.
addAllAttributes
(
attributes
);
}
}
/**
* Add the given attribute if the model does not already contain such an attribute.
* @param name the name of the attribute to check and add
* @param value the value of the attribute
*/
public
void
mergeAttribute
(
String
name
,
Object
value
)
{
if
(!
containsAttribute
(
name
))
{
model
.
addAttribute
(
name
,
value
);
}
}
}
\ No newline at end of file
org.springframework.web/src/test/java/org/springframework/web/method/annotation/ModelFactoryTests.java
浏览文件 @
6fe0ff9e
...
...
@@ -32,9 +32,7 @@ import org.junit.Before;
import
org.junit.Test
;
import
org.springframework.core.LocalVariableTableParameterNameDiscoverer
;
import
org.springframework.mock.web.MockHttpServletRequest
;
import
org.springframework.ui.ExtendedModelMap
;
import
org.springframework.ui.Model
;
import
org.springframework.ui.ModelMap
;
import
org.springframework.validation.BindingResult
;
import
org.springframework.web.bind.WebDataBinder
;
import
org.springframework.web.bind.annotation.ModelAttribute
;
...
...
@@ -48,6 +46,7 @@ import org.springframework.web.context.request.ServletWebRequest;
import
org.springframework.web.method.annotation.support.ModelMethodProcessor
;
import
org.springframework.web.method.support.HandlerMethodArgumentResolverComposite
;
import
org.springframework.web.method.support.InvocableHandlerMethod
;
import
org.springframework.web.method.support.ModelAndViewContainer
;
/**
* Text fixture for {@link ModelFactory} unit tests.
...
...
@@ -64,6 +63,8 @@ public class ModelFactoryTests {
private
InvocableHandlerMethod
requestMethod
;
private
ModelAndViewContainer
mavContainer
;
@Before
public
void
setUp
()
throws
Exception
{
Object
handler
=
new
ModelHandler
();
...
...
@@ -73,38 +74,39 @@ public class ModelFactoryTests {
this
.
sessionAttributeStore
=
new
DefaultSessionAttributeStore
();
this
.
handlerSessionAttributeStore
=
new
SessionAttributesHandler
(
handler
.
getClass
(),
sessionAttributeStore
);
this
.
mavContainer
=
new
ModelAndViewContainer
();
this
.
webRequest
=
new
ServletWebRequest
(
new
MockHttpServletRequest
());
}
@Test
public
void
createModel
()
throws
Exception
{
ModelMap
model
=
createFactory
(
new
ModelHandler
(),
"model"
,
Model
.
class
).
createModel
(
webRequest
,
requestMethod
);
assertEquals
(
Boolean
.
TRUE
,
m
odel
.
get
(
"model"
));
createFactory
(
new
ModelHandler
(),
"model"
,
Model
.
class
).
initModel
(
webRequest
,
mavContainer
,
requestMethod
);
assertEquals
(
Boolean
.
TRUE
,
m
avContainer
.
getAttribute
(
"model"
));
}
@Test
public
void
createModelWithName
()
throws
Exception
{
ModelMap
model
=
createFactory
(
new
ModelHandler
(),
"modelWithName"
).
createModel
(
webRequest
,
requestMethod
);
assertEquals
(
Boolean
.
TRUE
,
m
odel
.
get
(
"name"
));
createFactory
(
new
ModelHandler
(),
"modelWithName"
).
initModel
(
webRequest
,
mavContainer
,
requestMethod
);
assertEquals
(
Boolean
.
TRUE
,
m
avContainer
.
getAttribute
(
"name"
));
}
@Test
public
void
createModelWithDefaultName
()
throws
Exception
{
ModelMap
model
=
createFactory
(
new
ModelHandler
(),
"modelWithDefaultName"
).
createModel
(
webRequest
,
requestMethod
);
assertEquals
(
Boolean
.
TRUE
,
m
odel
.
get
(
"boolean"
));
createFactory
(
new
ModelHandler
(),
"modelWithDefaultName"
).
initModel
(
webRequest
,
mavContainer
,
requestMethod
);
assertEquals
(
Boolean
.
TRUE
,
m
avContainer
.
getAttribute
(
"boolean"
));
}
@Test
public
void
createModelWithExistingName
()
throws
Exception
{
ModelMap
model
=
createFactory
(
new
ModelHandler
(),
"modelWithName"
).
createModel
(
webRequest
,
requestMethod
);
assertEquals
(
Boolean
.
TRUE
,
m
odel
.
get
(
"name"
));
createFactory
(
new
ModelHandler
(),
"modelWithName"
).
initModel
(
webRequest
,
mavContainer
,
requestMethod
);
assertEquals
(
Boolean
.
TRUE
,
m
avContainer
.
getAttribute
(
"name"
));
}
@Test
public
void
createModelWithNullAttribute
()
throws
Exception
{
ModelMap
model
=
createFactory
(
new
ModelHandler
(),
"modelWithNullAttribute"
).
createModel
(
webRequest
,
requestMethod
);
assertTrue
(
m
odel
.
containsKey
(
"name"
));
assertNull
(
m
odel
.
get
(
"name"
));
createFactory
(
new
ModelHandler
(),
"modelWithNullAttribute"
).
initModel
(
webRequest
,
mavContainer
,
requestMethod
);
assertTrue
(
m
avContainer
.
containsAttribute
(
"name"
));
assertNull
(
m
avContainer
.
getAttribute
(
"name"
));
}
@Test
...
...
@@ -114,8 +116,8 @@ public class ModelFactoryTests {
// Query attribute to associate it with the handler type
assertTrue
(
handlerSessionAttributeStore
.
isHandlerSessionAttribute
(
"sessionAttr"
,
null
));
ModelMap
model
=
createFactory
(
new
ModelHandler
(),
"model"
,
Model
.
class
).
createModel
(
webRequest
,
requestMethod
);
assertEquals
(
"sessionAttrValue"
,
m
odel
.
get
(
"sessionAttr"
));
createFactory
(
new
ModelHandler
(),
"model"
,
Model
.
class
).
initModel
(
webRequest
,
mavContainer
,
requestMethod
);
assertEquals
(
"sessionAttrValue"
,
m
avContainer
.
getAttribute
(
"sessionAttr"
));
}
@Test
...
...
@@ -128,8 +130,7 @@ public class ModelFactoryTests {
String
attrName
=
"attr1"
;
Object
attrValue
=
new
Object
();
ModelMap
actualModel
=
new
ExtendedModelMap
();
actualModel
.
addAttribute
(
attrName
,
attrValue
);
mavContainer
.
addAttribute
(
attrName
,
attrValue
);
WebDataBinder
dataBinder
=
new
WebDataBinder
(
attrValue
,
attrName
);
...
...
@@ -138,11 +139,11 @@ public class ModelFactoryTests {
replay
(
binderFactory
);
ModelFactory
modelFactory
=
new
ModelFactory
(
null
,
binderFactory
,
sessionAttributeStore
);
modelFactory
.
update
Attributes
(
webRequest
,
new
SimpleSessionStatus
(),
actualModel
,
null
);
modelFactory
.
update
Model
(
webRequest
,
mavContainer
,
new
SimpleSessionStatus
()
);
assertEquals
(
attrValue
,
actualModel
.
remove
(
attrName
));
assertSame
(
dataBinder
.
getBindingResult
(),
actualModel
.
remove
(
bindingResultKey
(
attrName
)));
assertEquals
(
0
,
actualModel
.
size
());
assertEquals
(
attrValue
,
mavContainer
.
getModel
()
.
remove
(
attrName
));
assertSame
(
dataBinder
.
getBindingResult
(),
mavContainer
.
getModel
()
.
remove
(
bindingResultKey
(
attrName
)));
assertEquals
(
0
,
mavContainer
.
getModel
()
.
size
());
verify
(
binderFactory
);
}
...
...
org.springframework.web/src/test/java/org/springframework/web/method/annotation/support/ErrorsMethodHandlerArgumentResolverTests.java
浏览文件 @
6fe0ff9e
...
...
@@ -24,14 +24,12 @@ import org.junit.Before;
import
org.junit.Test
;
import
org.springframework.core.MethodParameter
;
import
org.springframework.mock.web.MockHttpServletRequest
;
import
org.springframework.ui.ExtendedModelMap
;
import
org.springframework.ui.ModelMap
;
import
org.springframework.validation.BindingResult
;
import
org.springframework.validation.Errors
;
import
org.springframework.web.bind.WebDataBinder
;
import
org.springframework.web.context.request.NativeWebRequest
;
import
org.springframework.web.context.request.ServletWebRequest
;
import
org.springframework.web.method.
annotation.support.ErrorsMethodArgumentResolv
er
;
import
org.springframework.web.method.
support.ModelAndViewContain
er
;
/**
* Test fixture for {@link ErrorsMethodArgumentResolver} unit tests.
...
...
@@ -66,15 +64,15 @@ public class ErrorsMethodHandlerArgumentResolverTests {
WebDataBinder
dataBinder
=
new
WebDataBinder
(
new
Object
(),
"attr"
);
BindingResult
bindingResult
=
dataBinder
.
getBindingResult
();
Model
Map
model
=
new
ExtendedModelMap
();
m
odel
.
addAttribute
(
"ignore1"
,
"value1"
);
m
odel
.
addAttribute
(
"ignore2"
,
"value2"
);
m
odel
.
addAttribute
(
"ignore3"
,
"value3"
);
m
odel
.
addAttribute
(
"ignore4"
,
"value4"
);
m
odel
.
addAttribute
(
"ignore5"
,
"value5"
);
m
odel
.
addAllAttributes
(
bindingResult
.
getModel
());
// Predictable iteration order of model keys important!
Model
AndViewContainer
mavContainer
=
new
ModelAndViewContainer
();
m
avContainer
.
addAttribute
(
"ignore1"
,
"value1"
);
m
avContainer
.
addAttribute
(
"ignore2"
,
"value2"
);
m
avContainer
.
addAttribute
(
"ignore3"
,
"value3"
);
m
avContainer
.
addAttribute
(
"ignore4"
,
"value4"
);
m
avContainer
.
addAttribute
(
"ignore5"
,
"value5"
);
m
avContainer
.
addAllAttributes
(
bindingResult
.
getModel
());
// Predictable iteration order of model keys important!
Object
actual
=
resolver
.
resolveArgument
(
errorsParam
,
m
odel
,
webRequest
,
null
);
Object
actual
=
resolver
.
resolveArgument
(
errorsParam
,
m
avContainer
,
webRequest
,
null
);
assertSame
(
actual
,
bindingResult
);
}
...
...
@@ -89,14 +87,14 @@ public class ErrorsMethodHandlerArgumentResolverTests {
WebDataBinder
binder2
=
new
WebDataBinder
(
target1
,
"attr2"
);
BindingResult
bindingResult2
=
binder2
.
getBindingResult
();
Model
Map
model
=
new
ExtendedModelMap
();
m
odel
.
addAttribute
(
"attr1"
,
target1
);
m
odel
.
addAttribute
(
"attr2"
,
target2
);
m
odel
.
addAttribute
(
"filler"
,
"fillerValue"
);
m
odel
.
addAllAttributes
(
bindingResult1
.
getModel
());
m
odel
.
addAllAttributes
(
bindingResult2
.
getModel
());
Model
AndViewContainer
mavContainer
=
new
ModelAndViewContainer
();
m
avContainer
.
addAttribute
(
"attr1"
,
target1
);
m
avContainer
.
addAttribute
(
"attr2"
,
target2
);
m
avContainer
.
addAttribute
(
"filler"
,
"fillerValue"
);
m
avContainer
.
addAllAttributes
(
bindingResult1
.
getModel
());
m
avContainer
.
addAllAttributes
(
bindingResult2
.
getModel
());
Object
actual
=
resolver
.
resolveArgument
(
errorsParam
,
m
odel
,
webRequest
,
null
);
Object
actual
=
resolver
.
resolveArgument
(
errorsParam
,
m
avContainer
,
webRequest
,
null
);
assertSame
(
"Should resolve to the latest BindingResult added"
,
actual
,
bindingResult2
);
}
...
...
@@ -106,16 +104,16 @@ public class ErrorsMethodHandlerArgumentResolverTests {
WebDataBinder
dataBinder
=
new
WebDataBinder
(
new
Object
(),
"attr"
);
BindingResult
bindingResult
=
dataBinder
.
getBindingResult
();
Model
Map
model
=
new
ExtendedModelMap
();
m
odel
.
addAllAttributes
(
bindingResult
.
getModel
());
m
odel
.
addAttribute
(
"ignore1"
,
"value1"
);
Model
AndViewContainer
mavContainer
=
new
ModelAndViewContainer
();
m
avContainer
.
addAllAttributes
(
bindingResult
.
getModel
());
m
avContainer
.
addAttribute
(
"ignore1"
,
"value1"
);
resolver
.
resolveArgument
(
errorsParam
,
m
odel
,
webRequest
,
null
);
resolver
.
resolveArgument
(
errorsParam
,
m
avContainer
,
webRequest
,
null
);
}
@Test
(
expected
=
IllegalStateException
.
class
)
public
void
noBindingResult
()
throws
Exception
{
resolver
.
resolveArgument
(
errorsParam
,
new
ExtendedModelMap
(),
webRequest
,
null
);
resolver
.
resolveArgument
(
errorsParam
,
new
ModelAndViewContainer
(),
webRequest
,
null
);
}
@SuppressWarnings
(
"unused"
)
...
...
org.springframework.web/src/test/java/org/springframework/web/method/annotation/support/ModelAttributeMethodProcessorTests.java
浏览文件 @
6fe0ff9e
...
...
@@ -42,8 +42,6 @@ import org.junit.Test;
import
org.springframework.beans.TestBean
;
import
org.springframework.core.MethodParameter
;
import
org.springframework.mock.web.MockHttpServletRequest
;
import
org.springframework.ui.ExtendedModelMap
;
import
org.springframework.ui.ModelMap
;
import
org.springframework.validation.BindException
;
import
org.springframework.validation.Errors
;
import
org.springframework.web.bind.WebDataBinder
;
...
...
@@ -77,7 +75,7 @@ public class ModelAttributeMethodProcessorTests {
private
MethodParameter
notAnnotatedReturnParam
;
private
Model
Map
model
;
private
Model
AndViewContainer
mavContainer
;
private
NativeWebRequest
webRequest
;
...
...
@@ -97,7 +95,7 @@ public class ModelAttributeMethodProcessorTests {
this
.
annotatedReturnParam
=
new
MethodParameter
(
getClass
().
getDeclaredMethod
(
"annotatedReturnValue"
),
-
1
);
this
.
notAnnotatedReturnParam
=
new
MethodParameter
(
getClass
().
getDeclaredMethod
(
"notAnnotatedReturnValue"
),
-
1
);
m
odel
=
new
ExtendedModelMap
();
m
avContainer
=
new
ModelAndViewContainer
();
this
.
webRequest
=
new
ServletWebRequest
(
new
MockHttpServletRequest
());
}
...
...
@@ -139,7 +137,7 @@ public class ModelAttributeMethodProcessorTests {
private
void
createBinderFromModelAttr
(
String
expectedAttrName
,
MethodParameter
param
)
throws
Exception
{
Object
target
=
new
TestBean
();
m
odel
.
addAttribute
(
expectedAttrName
,
target
);
m
avContainer
.
addAttribute
(
expectedAttrName
,
target
);
WebDataBinder
dataBinder
=
new
WebRequestDataBinder
(
null
);
...
...
@@ -147,7 +145,7 @@ public class ModelAttributeMethodProcessorTests {
expect
(
binderFactory
.
createBinder
(
webRequest
,
target
,
expectedAttrName
)).
andReturn
(
dataBinder
);
replay
(
binderFactory
);
processor
.
resolveArgument
(
param
,
m
odel
,
webRequest
,
binderFactory
);
processor
.
resolveArgument
(
param
,
m
avContainer
,
webRequest
,
binderFactory
);
verify
(
binderFactory
);
}
...
...
@@ -160,7 +158,7 @@ public class ModelAttributeMethodProcessorTests {
expect
(
factory
.
createBinder
((
NativeWebRequest
)
anyObject
(),
notNull
(),
eq
(
"attrName"
))).
andReturn
(
dataBinder
);
replay
(
factory
);
processor
.
resolveArgument
(
annotatedParam
,
m
odel
,
webRequest
,
factory
);
processor
.
resolveArgument
(
annotatedParam
,
m
avContainer
,
webRequest
,
factory
);
verify
(
factory
);
}
...
...
@@ -168,14 +166,14 @@ public class ModelAttributeMethodProcessorTests {
@Test
public
void
bindAndValidate
()
throws
Exception
{
Object
target
=
new
TestBean
();
m
odel
.
addAttribute
(
"attrName"
,
target
);
m
avContainer
.
addAttribute
(
"attrName"
,
target
);
StubRequestDataBinder
dataBinder
=
new
StubRequestDataBinder
(
target
);
WebDataBinderFactory
binderFactory
=
createMock
(
WebDataBinderFactory
.
class
);
expect
(
binderFactory
.
createBinder
(
webRequest
,
target
,
"attrName"
)).
andReturn
(
dataBinder
);
replay
(
binderFactory
);
processor
.
resolveArgument
(
annotatedParam
,
m
odel
,
webRequest
,
binderFactory
);
processor
.
resolveArgument
(
annotatedParam
,
m
avContainer
,
webRequest
,
binderFactory
);
assertTrue
(
dataBinder
.
isBindInvoked
());
assertTrue
(
dataBinder
.
isValidateInvoked
());
...
...
@@ -184,7 +182,7 @@ public class ModelAttributeMethodProcessorTests {
@Test
(
expected
=
BindException
.
class
)
public
void
bindAndFail
()
throws
Exception
{
Object
target
=
new
TestBean
();
m
odel
.
addAttribute
(
target
);
m
avContainer
.
getModel
()
.
addAttribute
(
target
);
StubRequestDataBinder
dataBinder
=
new
StubRequestDataBinder
(
target
);
dataBinder
.
getBindingResult
().
reject
(
"error"
);
...
...
@@ -192,12 +190,12 @@ public class ModelAttributeMethodProcessorTests {
expect
(
binderFactory
.
createBinder
(
webRequest
,
target
,
"testBean"
)).
andReturn
(
dataBinder
);
replay
(
binderFactory
);
processor
.
resolveArgument
(
notAnnotatedParam
,
m
odel
,
webRequest
,
binderFactory
);
processor
.
resolveArgument
(
notAnnotatedParam
,
m
avContainer
,
webRequest
,
binderFactory
);
}
@Test
public
void
handleAnnotatedReturnValue
()
throws
Exception
{
ModelAndViewContainer
mavContainer
=
new
ModelAndViewContainer
(
model
);
ModelAndViewContainer
mavContainer
=
new
ModelAndViewContainer
();
processor
.
handleReturnValue
(
"expected"
,
annotatedReturnParam
,
mavContainer
,
webRequest
);
assertEquals
(
"expected"
,
mavContainer
.
getModel
().
get
(
"modelAttrName"
));
...
...
@@ -206,7 +204,7 @@ public class ModelAttributeMethodProcessorTests {
@Test
public
void
handleNotAnnotatedReturnValue
()
throws
Exception
{
TestBean
testBean
=
new
TestBean
(
"expected"
);
ModelAndViewContainer
mavContainer
=
new
ModelAndViewContainer
(
model
);
ModelAndViewContainer
mavContainer
=
new
ModelAndViewContainer
();
processor
.
handleReturnValue
(
testBean
,
notAnnotatedReturnParam
,
mavContainer
,
webRequest
);
assertSame
(
testBean
,
mavContainer
.
getModel
().
get
(
"testBean"
));
...
...
org.springframework.web/src/test/java/org/springframework/web/method/annotation/support/ModelMethodProcessorTests.java
浏览文件 @
6fe0ff9e
...
...
@@ -88,13 +88,13 @@ public class ModelMethodProcessorTests {
@Test
public
void
resolveArgumentValue
()
throws
Exception
{
ExtendedModelMap
model
=
new
ExtendedModelMap
();
ModelAndViewContainer
mavContainer
=
new
ModelAndViewContainer
();
Object
result
=
resolver
.
resolveArgument
(
modelParameter
,
m
odel
,
webRequest
,
null
);
assertSame
(
m
odel
,
result
);
Object
result
=
resolver
.
resolveArgument
(
modelParameter
,
m
avContainer
,
webRequest
,
null
);
assertSame
(
m
avContainer
.
getModel
()
,
result
);
result
=
resolver
.
resolveArgument
(
mapParameter
,
m
odel
,
webRequest
,
null
);
assertSame
(
m
odel
,
result
);
result
=
resolver
.
resolveArgument
(
mapParameter
,
m
avContainer
,
webRequest
,
null
);
assertSame
(
m
avContainer
.
getModel
()
,
result
);
}
@Test
...
...
org.springframework.web/src/test/java/org/springframework/web/method/support/HandlerMethodArgumentResolverCompositeTests.java
浏览文件 @
6fe0ff9e
...
...
@@ -78,18 +78,6 @@ public class HandlerMethodArgumentResolverCompositeTests {
this
.
composite
.
resolveArgument
(
paramString
,
null
,
null
,
null
);
}
@Test
public
void
argResolverUsesResponse
()
throws
Exception
{
registerResolver
(
Integer
.
class
,
null
,
true
);
assertTrue
(
this
.
composite
.
usesResponseArgument
(
paramInteger
));
}
@Test
public
void
argResolverDoesntUseResponse
()
throws
Exception
{
registerResolver
(
Integer
.
class
,
null
,
false
);
assertFalse
(
this
.
composite
.
usesResponseArgument
(
paramInteger
));
}
protected
StubArgumentResolver
registerResolver
(
Class
<?>
supportedType
,
Object
stubValue
,
boolean
usesResponse
)
{
StubArgumentResolver
resolver
=
new
StubArgumentResolver
(
supportedType
,
stubValue
,
usesResponse
);
this
.
composite
.
registerArgumentResolver
(
resolver
);
...
...
org.springframework.web/src/test/java/org/springframework/web/method/support/HandlerMethodReturnValueHandlerCompositeTests.java
浏览文件 @
6fe0ff9e
...
...
@@ -47,7 +47,7 @@ public class HandlerMethodReturnValueHandlerCompositeTests {
this
.
paramInteger
=
new
MethodParameter
(
getClass
().
getDeclaredMethod
(
"handleInteger"
),
-
1
);
this
.
paramString
=
new
MethodParameter
(
getClass
().
getDeclaredMethod
(
"handleString"
),
-
1
);
mavContainer
=
new
ModelAndViewContainer
(
null
);
mavContainer
=
new
ModelAndViewContainer
();
}
@Test
...
...
@@ -81,18 +81,6 @@ public class HandlerMethodReturnValueHandlerCompositeTests {
registerReturnValueHandler
(
Integer
.
class
,
false
);
this
.
composite
.
handleReturnValue
(
"value"
,
paramString
,
null
,
null
);
}
@Test
public
void
returnValueHandlerUsesResponse
()
throws
Exception
{
registerReturnValueHandler
(
Integer
.
class
,
true
);
assertTrue
(
this
.
composite
.
usesResponseArgument
(
paramInteger
));
}
@Test
public
void
returnValueHandlerDosntUseResponse
()
throws
Exception
{
registerReturnValueHandler
(
Integer
.
class
,
false
);
assertFalse
(
this
.
composite
.
usesResponseArgument
(
paramInteger
));
}
protected
StubReturnValueHandler
registerReturnValueHandler
(
Class
<?>
returnType
,
boolean
usesResponse
)
{
StubReturnValueHandler
handler
=
new
StubReturnValueHandler
(
returnType
,
usesResponse
);
...
...
org.springframework.web/src/test/java/org/springframework/web/method/support/InvocableHandlerMethodTests.java
浏览文件 @
6fe0ff9e
...
...
@@ -17,7 +17,6 @@
package
org.springframework.web.method.support
;
import
static
org
.
junit
.
Assert
.
assertEquals
;
import
static
org
.
junit
.
Assert
.
assertTrue
;
import
java.lang.reflect.Method
;
...
...
@@ -84,14 +83,6 @@ public class InvocableHandlerMethodTests {
assertEquals
(
"intArg"
,
resolver
.
getResolvedParameterNames
().
get
(
0
).
getParameterName
());
}
@Test
public
void
usesResponseArgResolver
()
throws
Exception
{
InvocableHandlerMethod
requestMethod
=
handlerMethod
(
new
Handler
(),
"usesResponse"
,
int
.
class
);
registerResolver
(
int
.
class
,
99
,
true
);
assertTrue
(
requestMethod
.
usesResponseArgument
());
}
private
InvocableHandlerMethod
handlerMethod
(
Object
handler
,
String
methodName
,
Class
<?>...
paramTypes
)
throws
Exception
{
Method
method
=
handler
.
getClass
().
getDeclaredMethod
(
methodName
,
paramTypes
);
...
...
org.springframework.web/src/test/java/org/springframework/web/method/support/StubArgumentResolver.java
浏览文件 @
6fe0ff9e
...
...
@@ -20,10 +20,8 @@ import java.util.ArrayList;
import
java.util.List
;
import
org.springframework.core.MethodParameter
;
import
org.springframework.ui.ModelMap
;
import
org.springframework.web.bind.support.WebDataBinderFactory
;
import
org.springframework.web.context.request.NativeWebRequest
;
import
org.springframework.web.method.support.HandlerMethodArgumentResolver
;
/**
* Resolves a method argument from a stub value. Records all resolved parameters.
...
...
@@ -58,8 +56,10 @@ public class StubArgumentResolver implements HandlerMethodArgumentResolver {
return
parameter
.
getParameterType
().
equals
(
this
.
supportedType
);
}
public
Object
resolveArgument
(
MethodParameter
parameter
,
ModelMap
model
,
NativeWebRequest
webRequest
,
WebDataBinderFactory
binderFactory
)
throws
Exception
{
public
Object
resolveArgument
(
MethodParameter
parameter
,
ModelAndViewContainer
mavContainer
,
NativeWebRequest
webRequest
,
WebDataBinderFactory
binderFactory
)
throws
Exception
{
this
.
resolvedParameters
.
add
(
parameter
);
return
this
.
stubValue
;
}
...
...
org.springframework.web/src/test/java/org/springframework/web/method/support/StubReturnValueHandler.java
浏览文件 @
6fe0ff9e
...
...
@@ -53,7 +53,7 @@ public class StubReturnValueHandler implements HandlerMethodReturnValueHandler {
NativeWebRequest
webRequest
)
throws
Exception
{
this
.
unhandledReturnValue
=
returnValue
;
if
(
returnValue
!=
null
)
{
mavContainer
.
add
Model
Attribute
(
Conventions
.
getVariableName
(
returnValue
),
returnValue
);
mavContainer
.
addAttribute
(
Conventions
.
getVariableName
(
returnValue
),
returnValue
);
}
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录