Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
普通程序员一名
spring-framework
提交
806e79b1
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,发现更多精彩内容 >>
提交
806e79b1
编写于
1月 26, 2016
作者:
R
Rossen Stoyanchev
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Polish
上级
e62ada89
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
227 addition
and
245 deletion
+227
-245
spring-web/src/main/java/org/springframework/web/method/annotation/ModelAttributeMethodProcessor.java
.../web/method/annotation/ModelAttributeMethodProcessor.java
+22
-32
spring-web/src/main/java/org/springframework/web/method/annotation/ModelFactory.java
...g/springframework/web/method/annotation/ModelFactory.java
+55
-48
spring-web/src/test/java/org/springframework/web/method/annotation/ModelAttributeMethodProcessorTests.java
...method/annotation/ModelAttributeMethodProcessorTests.java
+82
-87
spring-web/src/test/java/org/springframework/web/method/annotation/ModelFactoryTests.java
...ingframework/web/method/annotation/ModelFactoryTests.java
+68
-78
未找到文件。
spring-web/src/main/java/org/springframework/web/method/annotation/ModelAttributeMethodProcessor.java
浏览文件 @
806e79b1
...
...
@@ -38,23 +38,24 @@ import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
import
org.springframework.web.method.support.ModelAndViewContainer
;
/**
* Resolve
s method arguments annotated with {@code @ModelAttribute} and handles
* return values from
methods annotated with {@code @ModelAttribute}
.
* Resolve
{@code @ModelAttribute} annotated method arguments and handle
* return values from
{@code @ModelAttribute} annotated methods
.
*
* <p>Model attributes are obtained from the model or
if not found possibly
* c
reated with a default constructor if it is available. Once created, the
*
attributed is populated with request data via data binding and also
*
validation may be applied if the argument is annotated with
*
{@code @javax.validation.Vali
d}.
* <p>Model attributes are obtained from the model or
created with a default
* c
onstructor (and then added to the model). Once created the attribute is
*
populated via data binding to Servlet request parameters. Validation may be
*
applied if the argument is annotated with {@code @javax.validation.Valid}.
*
or {@link @Validate
d}.
*
* <p>When this handler is created with {@code annotationNotRequired=true}
,
* <p>When this handler is created with {@code annotationNotRequired=true}
* any non-simple type argument and return value is regarded as a model
* attribute with or without the presence of an {@code @ModelAttribute}.
*
* @author Rossen Stoyanchev
* @since 3.1
*/
public
class
ModelAttributeMethodProcessor
implements
HandlerMethodArgumentResolver
,
HandlerMethodReturnValueHandler
{
public
class
ModelAttributeMethodProcessor
implements
HandlerMethodArgumentResolver
,
HandlerMethodReturnValueHandler
{
protected
final
Log
logger
=
LogFactory
.
getLog
(
getClass
());
...
...
@@ -62,6 +63,7 @@ public class ModelAttributeMethodProcessor implements HandlerMethodArgumentResol
/**
* Class constructor.
* @param annotationNotRequired if "true", non-simple method arguments and
* return values are considered model attributes with or without a
* {@code @ModelAttribute} annotation.
...
...
@@ -72,20 +74,14 @@ public class ModelAttributeMethodProcessor implements HandlerMethodArgumentResol
/**
* Returns {@code true} if the parameter is annotated with {@link ModelAttribute}
* or in default resolution mode, and also if it is not a simple type.
* Returns {@code true} if the parameter is annotated with
* {@link ModelAttribute} or, if in default resolution mode, for any
* method parameter that is not a simple type.
*/
@Override
public
boolean
supportsParameter
(
MethodParameter
parameter
)
{
if
(
parameter
.
hasParameterAnnotation
(
ModelAttribute
.
class
))
{
return
true
;
}
else
if
(
this
.
annotationNotRequired
)
{
return
!
BeanUtils
.
isSimpleProperty
(
parameter
.
getParameterType
());
}
else
{
return
false
;
}
return
(
parameter
.
hasParameterAnnotation
(
ModelAttribute
.
class
)
||
(
this
.
annotationNotRequired
&&
!
BeanUtils
.
isSimpleProperty
(
parameter
.
getParameterType
())));
}
/**
...
...
@@ -102,8 +98,8 @@ public class ModelAttributeMethodProcessor implements HandlerMethodArgumentResol
NativeWebRequest
webRequest
,
WebDataBinderFactory
binderFactory
)
throws
Exception
{
String
name
=
ModelFactory
.
getNameForParameter
(
parameter
);
Object
attribute
=
(
mavContainer
.
containsAttribute
(
name
)
?
mavContainer
.
getModel
().
get
(
name
)
:
createAttribute
(
name
,
parameter
,
binderFactory
,
webRequest
));
Object
attribute
=
(
mavContainer
.
containsAttribute
(
name
)
?
mavContainer
.
getModel
().
get
(
name
)
:
createAttribute
(
name
,
parameter
,
binderFactory
,
webRequest
));
WebDataBinder
binder
=
binderFactory
.
createBinder
(
webRequest
,
attribute
,
name
);
if
(
binder
.
getTarget
()
!=
null
)
{
...
...
@@ -182,19 +178,13 @@ public class ModelAttributeMethodProcessor implements HandlerMethodArgumentResol
/**
* Return {@code true} if there is a method-level {@code @ModelAttribute}
* or if it is a non-simple type when {@code annotationNotRequired=true}.
* or, in default resolution mode, for any return value type that is not
* a simple type.
*/
@Override
public
boolean
supportsReturnType
(
MethodParameter
returnType
)
{
if
(
returnType
.
getMethodAnnotation
(
ModelAttribute
.
class
)
!=
null
)
{
return
true
;
}
else
if
(
this
.
annotationNotRequired
)
{
return
!
BeanUtils
.
isSimpleProperty
(
returnType
.
getParameterType
());
}
else
{
return
false
;
}
return
(
returnType
.
getMethodAnnotation
(
ModelAttribute
.
class
)
!=
null
||
this
.
annotationNotRequired
&&
!
BeanUtils
.
isSimpleProperty
(
returnType
.
getParameterType
()));
}
/**
...
...
spring-web/src/main/java/org/springframework/web/method/annotation/ModelFactory.java
浏览文件 @
806e79b1
/*
* Copyright 2002-201
4
the original author or authors.
* Copyright 2002-201
6
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.
...
...
@@ -45,14 +45,15 @@ import org.springframework.web.method.support.InvocableHandlerMethod;
import
org.springframework.web.method.support.ModelAndViewContainer
;
/**
*
Provides methods to initialize
the {@link Model} before controller method
* invocation and
to update it afterwards
.
*
Assist with initialization of
the {@link Model} before controller method
* invocation and
with updates to it after the invocation
.
*
* <p>On initialization, the model is populated with attributes from the session
* and by invoking methods annotated with {@code @ModelAttribute}.
* <p>On initialization the model is populated with attributes temporarily
* stored in the session and through the invocation of {@code @ModelAttribute}
* methods.
*
* <p>On update
,
model attributes are synchronized with the session and also
* {@link BindingResult} attributes are added
where
missing.
* <p>On update model attributes are synchronized with the session and also
* {@link BindingResult} attributes are added
if
missing.
*
* @author Rossen Stoyanchev
* @since 3.1
...
...
@@ -61,6 +62,7 @@ public final class ModelFactory {
private
static
final
Log
logger
=
LogFactory
.
getLog
(
ModelFactory
.
class
);
private
final
List
<
ModelMethod
>
modelMethods
=
new
ArrayList
<
ModelMethod
>();
private
final
WebDataBinderFactory
dataBinderFactory
;
...
...
@@ -70,22 +72,23 @@ public final class ModelFactory {
/**
* Create a new instance with the given {@code @ModelAttribute} methods.
* @param
invocable
Methods the {@code @ModelAttribute} methods to invoke
* @param
dataB
inderFactory for preparation of {@link BindingResult} attributes
* @param
sessionAttributes
Handler for access to session attributes
* @param
handler
Methods the {@code @ModelAttribute} methods to invoke
* @param
b
inderFactory for preparation of {@link BindingResult} attributes
* @param
attribute
Handler for access to session attributes
*/
public
ModelFactory
(
List
<
InvocableHandlerMethod
>
invocableMethods
,
WebDataBinderFactory
dataBinderFactory
,
SessionAttributesHandler
sessionAttributes
Handler
)
{
public
ModelFactory
(
List
<
InvocableHandlerMethod
>
handlerMethods
,
WebDataBinderFactory
binderFactory
,
SessionAttributesHandler
attribute
Handler
)
{
if
(
invocable
Methods
!=
null
)
{
for
(
InvocableHandlerMethod
method
:
invocable
Methods
)
{
this
.
modelMethods
.
add
(
new
ModelMethod
(
m
ethod
));
if
(
handler
Methods
!=
null
)
{
for
(
InvocableHandlerMethod
handlerMethod
:
handler
Methods
)
{
this
.
modelMethods
.
add
(
new
ModelMethod
(
handlerM
ethod
));
}
}
this
.
dataBinderFactory
=
dataB
inderFactory
;
this
.
sessionAttributesHandler
=
sessionAttributes
Handler
;
this
.
dataBinderFactory
=
b
inderFactory
;
this
.
sessionAttributesHandler
=
attribute
Handler
;
}
/**
* Populate the model in the following order:
* <ol>
...
...
@@ -96,25 +99,26 @@ public final class ModelFactory {
* an exception if necessary.
* </ol>
* @param request the current request
* @param
mavC
ontainer a container with the model to be initialized
* @param
c
ontainer a container with the model to be initialized
* @param handlerMethod the method for which the model is initialized
* @throws Exception may arise from {@code @ModelAttribute} methods
*/
public
void
initModel
(
NativeWebRequest
request
,
ModelAndViewContainer
mavContainer
,
HandlerMethod
handlerMethod
)
throws
Exception
{
public
void
initModel
(
NativeWebRequest
request
,
ModelAndViewContainer
container
,
HandlerMethod
handlerMethod
)
throws
Exception
{
Map
<
String
,
?>
sessionAttributes
=
this
.
sessionAttributesHandler
.
retrieveAttributes
(
request
);
mavC
ontainer
.
mergeAttributes
(
sessionAttributes
);
c
ontainer
.
mergeAttributes
(
sessionAttributes
);
invokeModelAttributeMethods
(
request
,
mavC
ontainer
);
invokeModelAttributeMethods
(
request
,
c
ontainer
);
for
(
String
name
:
findSessionAttributeArguments
(
handlerMethod
))
{
if
(!
mavC
ontainer
.
containsAttribute
(
name
))
{
if
(!
c
ontainer
.
containsAttribute
(
name
))
{
Object
value
=
this
.
sessionAttributesHandler
.
retrieveAttribute
(
request
,
name
);
if
(
value
==
null
)
{
throw
new
HttpSessionRequiredException
(
"Expected session attribute '"
+
name
+
"'"
);
throw
new
HttpSessionRequiredException
(
"Expected session attribute '"
+
name
+
"'"
);
}
mavC
ontainer
.
addAttribute
(
name
,
value
);
c
ontainer
.
addAttribute
(
name
,
value
);
}
}
}
...
...
@@ -123,30 +127,31 @@ public final class ModelFactory {
* Invoke model attribute methods to populate the model.
* Attributes are added only if not already present in the model.
*/
private
void
invokeModelAttributeMethods
(
NativeWebRequest
request
,
ModelAndViewContainer
mavContainer
)
throws
Exception
{
private
void
invokeModelAttributeMethods
(
NativeWebRequest
request
,
ModelAndViewContainer
container
)
throws
Exception
{
while
(!
this
.
modelMethods
.
isEmpty
())
{
InvocableHandlerMethod
attrMethod
=
getNextModelMethod
(
mavContainer
).
getHandlerMethod
();
String
modelName
=
attrMethod
.
getMethodAnnotation
(
ModelAttribute
.
class
).
value
();
if
(
mavContainer
.
containsAttribute
(
modelName
))
{
InvocableHandlerMethod
modelMethod
=
getNextModelMethod
(
container
).
getHandlerMethod
();
ModelAttribute
annot
=
modelMethod
.
getMethodAnnotation
(
ModelAttribute
.
class
);
String
modelName
=
annot
.
value
();
if
(
container
.
containsAttribute
(
modelName
))
{
continue
;
}
Object
returnValue
=
attrMethod
.
invokeForRequest
(
request
,
mavC
ontainer
);
Object
returnValue
=
modelMethod
.
invokeForRequest
(
request
,
c
ontainer
);
if
(!
attr
Method
.
isVoid
()){
String
returnValueName
=
getNameForReturnValue
(
returnValue
,
attr
Method
.
getReturnType
());
if
(!
mavC
ontainer
.
containsAttribute
(
returnValueName
))
{
mavC
ontainer
.
addAttribute
(
returnValueName
,
returnValue
);
if
(!
model
Method
.
isVoid
()){
String
returnValueName
=
getNameForReturnValue
(
returnValue
,
model
Method
.
getReturnType
());
if
(!
c
ontainer
.
containsAttribute
(
returnValueName
))
{
c
ontainer
.
addAttribute
(
returnValueName
,
returnValue
);
}
}
}
}
private
ModelMethod
getNextModelMethod
(
ModelAndViewContainer
mavC
ontainer
)
{
private
ModelMethod
getNextModelMethod
(
ModelAndViewContainer
c
ontainer
)
{
for
(
ModelMethod
modelMethod
:
this
.
modelMethods
)
{
if
(
modelMethod
.
checkDependencies
(
mavC
ontainer
))
{
if
(
modelMethod
.
checkDependencies
(
c
ontainer
))
{
if
(
logger
.
isTraceEnabled
())
{
logger
.
trace
(
"Selected @ModelAttribute method "
+
modelMethod
);
}
...
...
@@ -157,7 +162,7 @@ public final class ModelFactory {
ModelMethod
modelMethod
=
this
.
modelMethods
.
get
(
0
);
if
(
logger
.
isTraceEnabled
())
{
logger
.
trace
(
"Selected @ModelAttribute method (not present: "
+
modelMethod
.
getUnresolvedDependencies
(
mavC
ontainer
)+
") "
+
modelMethod
);
modelMethod
.
getUnresolvedDependencies
(
c
ontainer
)+
") "
+
modelMethod
);
}
this
.
modelMethods
.
remove
(
modelMethod
);
return
modelMethod
;
...
...
@@ -171,7 +176,8 @@ public final class ModelFactory {
for
(
MethodParameter
parameter
:
handlerMethod
.
getMethodParameters
())
{
if
(
parameter
.
hasParameterAnnotation
(
ModelAttribute
.
class
))
{
String
name
=
getNameForParameter
(
parameter
);
if
(
this
.
sessionAttributesHandler
.
isHandlerSessionAttribute
(
name
,
parameter
.
getParameterType
()))
{
Class
<?>
paramType
=
parameter
.
getParameterType
();
if
(
this
.
sessionAttributesHandler
.
isHandlerSessionAttribute
(
name
,
paramType
))
{
result
.
add
(
name
);
}
}
...
...
@@ -189,8 +195,8 @@ public final class ModelFactory {
*/
public
static
String
getNameForParameter
(
MethodParameter
parameter
)
{
ModelAttribute
annot
=
parameter
.
getParameterAnnotation
(
ModelAttribute
.
class
);
String
attrN
ame
=
(
annot
!=
null
)
?
annot
.
value
()
:
null
;
return
StringUtils
.
hasText
(
attrName
)
?
attrName
:
Conventions
.
getVariableNameForParameter
(
parameter
);
String
n
ame
=
(
annot
!=
null
)
?
annot
.
value
()
:
null
;
return
StringUtils
.
hasText
(
name
)
?
name
:
Conventions
.
getVariableNameForParameter
(
parameter
);
}
/**
...
...
@@ -211,7 +217,8 @@ public final class ModelFactory {
}
else
{
Method
method
=
returnType
.
getMethod
();
Class
<?>
resolvedType
=
GenericTypeResolver
.
resolveReturnType
(
method
,
returnType
.
getContainingClass
());
Class
<?>
containingClass
=
returnType
.
getContainingClass
();
Class
<?>
resolvedType
=
GenericTypeResolver
.
resolveReturnType
(
method
,
containingClass
);
return
Conventions
.
getVariableNameForReturnType
(
method
,
resolvedType
,
returnValue
);
}
}
...
...
@@ -220,18 +227,18 @@ public final class ModelFactory {
* Promote model attributes listed as {@code @SessionAttributes} to the session.
* Add {@link BindingResult} attributes where necessary.
* @param request the current request
* @param
mavC
ontainer contains the model to update
* @param
c
ontainer contains the model to update
* @throws Exception if creating BindingResult attributes fails
*/
public
void
updateModel
(
NativeWebRequest
request
,
ModelAndViewContainer
mavC
ontainer
)
throws
Exception
{
ModelMap
defaultModel
=
mavC
ontainer
.
getDefaultModel
();
if
(
mavC
ontainer
.
getSessionStatus
().
isComplete
()){
public
void
updateModel
(
NativeWebRequest
request
,
ModelAndViewContainer
c
ontainer
)
throws
Exception
{
ModelMap
defaultModel
=
c
ontainer
.
getDefaultModel
();
if
(
c
ontainer
.
getSessionStatus
().
isComplete
()){
this
.
sessionAttributesHandler
.
cleanupAttributes
(
request
);
}
else
{
this
.
sessionAttributesHandler
.
storeAttributes
(
request
,
defaultModel
);
}
if
(!
mavContainer
.
isRequestHandled
()
&&
mavC
ontainer
.
getModel
()
==
defaultModel
)
{
if
(!
container
.
isRequestHandled
()
&&
c
ontainer
.
getModel
()
==
defaultModel
)
{
updateBindingResult
(
request
,
defaultModel
);
}
}
...
...
@@ -248,7 +255,7 @@ public final class ModelFactory {
String
bindingResultKey
=
BindingResult
.
MODEL_KEY_PREFIX
+
name
;
if
(!
model
.
containsAttribute
(
bindingResultKey
))
{
WebDataBinder
dataBinder
=
dataBinderFactory
.
createBinder
(
request
,
value
,
name
);
WebDataBinder
dataBinder
=
this
.
dataBinderFactory
.
createBinder
(
request
,
value
,
name
);
model
.
put
(
bindingResultKey
,
dataBinder
.
getBindingResult
());
}
}
...
...
spring-web/src/test/java/org/springframework/web/method/annotation/ModelAttributeMethodProcessorTests.java
浏览文件 @
806e79b1
...
...
@@ -24,6 +24,7 @@ import org.junit.Before;
import
org.junit.Test
;
import
org.springframework.core.MethodParameter
;
import
org.springframework.core.annotation.SynthesizingMethodParameter
;
import
org.springframework.mock.web.test.MockHttpServletRequest
;
import
org.springframework.tests.sample.beans.TestBean
;
import
org.springframework.validation.BindException
;
...
...
@@ -51,56 +52,53 @@ import static org.mockito.BDDMockito.*;
*/
public
class
ModelAttributeMethodProcessorTests
{
private
NativeWebRequest
request
;
private
ModelAndViewContainer
container
;
private
ModelAttributeMethodProcessor
processor
;
private
MethodParameter
paramNamedValidModelAttr
;
private
MethodParameter
paramErrors
;
private
MethodParameter
paramInt
;
private
MethodParameter
paramModelAttr
;
private
MethodParameter
paramNonSimpleType
;
private
MethodParameter
returnParamNamedModelAttr
;
private
MethodParameter
returnParamNonSimpleType
;
private
ModelAndViewContainer
mavContainer
;
private
NativeWebRequest
webRequest
;
@Before
public
void
setUp
()
throws
Exception
{
processor
=
new
ModelAttributeMethodProcessor
(
false
);
this
.
request
=
new
ServletWebRequest
(
new
MockHttpServletRequest
());
this
.
container
=
new
ModelAndViewContainer
();
this
.
processor
=
new
ModelAttributeMethodProcessor
(
false
);
Method
method
=
ModelAttributeHandler
.
class
.
getDeclaredMethod
(
"modelAttribute"
,
TestBean
.
class
,
Errors
.
class
,
int
.
class
,
TestBean
.
class
,
TestBean
.
class
);
paramNamedValidModelAttr
=
new
MethodParameter
(
method
,
0
);
paramErrors
=
new
MethodParameter
(
method
,
1
);
paramInt
=
new
MethodParameter
(
method
,
2
);
paramModelAttr
=
new
MethodParameter
(
method
,
3
);
paramNonSimpleType
=
new
MethodParameter
(
method
,
4
);
this
.
paramNamedValidModelAttr
=
new
Synthesizing
MethodParameter
(
method
,
0
);
this
.
paramErrors
=
new
Synthesizing
MethodParameter
(
method
,
1
);
this
.
paramInt
=
new
Synthesizing
MethodParameter
(
method
,
2
);
this
.
paramModelAttr
=
new
Synthesizing
MethodParameter
(
method
,
3
);
this
.
paramNonSimpleType
=
new
Synthesizing
MethodParameter
(
method
,
4
);
returnParamNamedModelAttr
=
new
MethodParameter
(
getClass
().
getDeclaredMethod
(
"annotatedReturnValue"
),
-
1
);
returnParamNonSimpleType
=
new
MethodParameter
(
getClass
().
getDeclaredMethod
(
"notAnnotatedReturnValue"
)
,
-
1
);
method
=
getClass
().
getDeclaredMethod
(
"annotatedReturnValue"
);
this
.
returnParamNamedModelAttr
=
new
MethodParameter
(
method
,
-
1
);
mavContainer
=
new
ModelAndViewContainer
();
webRequest
=
new
ServletWebRequest
(
new
MockHttpServletRequest
());
method
=
getClass
().
getDeclaredMethod
(
"notAnnotatedReturnValue"
);
this
.
returnParamNonSimpleType
=
new
MethodParameter
(
method
,
-
1
);
}
@Test
public
void
supportedParameters
()
throws
Exception
{
// Only @ModelAttribute arguments
assertTrue
(
processor
.
supportsParameter
(
paramNamedValidModelAttr
));
assertTrue
(
processor
.
supportsParameter
(
paramModelAttr
));
assertTrue
(
this
.
processor
.
supportsParameter
(
this
.
paramNamedValidModelAttr
));
assertTrue
(
this
.
processor
.
supportsParameter
(
this
.
paramModelAttr
));
assertFalse
(
processor
.
supportsParameter
(
paramErrors
));
assertFalse
(
processor
.
supportsParameter
(
paramInt
));
assertFalse
(
processor
.
supportsParameter
(
paramNonSimpleType
));
assertFalse
(
this
.
processor
.
supportsParameter
(
this
.
paramErrors
));
assertFalse
(
this
.
processor
.
supportsParameter
(
this
.
paramInt
));
assertFalse
(
this
.
processor
.
supportsParameter
(
this
.
paramNonSimpleType
));
}
@Test
...
...
@@ -108,135 +106,127 @@ public class ModelAttributeMethodProcessorTests {
processor
=
new
ModelAttributeMethodProcessor
(
true
);
// Only non-simple types, even if not annotated
assertTrue
(
processor
.
supportsParameter
(
paramNamedValidModelAttr
));
assertTrue
(
processor
.
supportsParameter
(
paramErrors
));
assertTrue
(
processor
.
supportsParameter
(
paramModelAttr
));
assertTrue
(
processor
.
supportsParameter
(
paramNonSimpleType
));
assertTrue
(
this
.
processor
.
supportsParameter
(
this
.
paramNamedValidModelAttr
));
assertTrue
(
this
.
processor
.
supportsParameter
(
this
.
paramErrors
));
assertTrue
(
this
.
processor
.
supportsParameter
(
this
.
paramModelAttr
));
assertTrue
(
this
.
processor
.
supportsParameter
(
this
.
paramNonSimpleType
));
assertFalse
(
processor
.
supportsParameter
(
paramInt
));
assertFalse
(
this
.
processor
.
supportsParameter
(
this
.
paramInt
));
}
@Test
public
void
supportedReturnTypes
()
throws
Exception
{
processor
=
new
ModelAttributeMethodProcessor
(
false
);
assertTrue
(
processor
.
supportsReturnType
(
returnParamNamedModelAttr
));
assertFalse
(
processor
.
supportsReturnType
(
returnParamNonSimpleType
));
assertTrue
(
this
.
processor
.
supportsReturnType
(
returnParamNamedModelAttr
));
assertFalse
(
this
.
processor
.
supportsReturnType
(
returnParamNonSimpleType
));
}
@Test
public
void
supportedReturnTypesInDefaultResolutionMode
()
throws
Exception
{
processor
=
new
ModelAttributeMethodProcessor
(
true
);
assertTrue
(
processor
.
supportsReturnType
(
returnParamNamedModelAttr
));
assertTrue
(
processor
.
supportsReturnType
(
returnParamNonSimpleType
));
assertTrue
(
this
.
processor
.
supportsReturnType
(
returnParamNamedModelAttr
));
assertTrue
(
this
.
processor
.
supportsReturnType
(
returnParamNonSimpleType
));
}
@Test
public
void
bindExceptionRequired
()
throws
Exception
{
assertTrue
(
processor
.
isBindExceptionRequired
(
null
,
paramNonSimpleType
));
}
@Test
public
void
bindExceptionNotRequired
()
throws
Exception
{
assertFalse
(
processor
.
isBindExceptionRequired
(
null
,
paramNamedValidModelAttr
));
assertTrue
(
this
.
processor
.
isBindExceptionRequired
(
null
,
this
.
paramNonSimpleType
));
assertFalse
(
this
.
processor
.
isBindExceptionRequired
(
null
,
this
.
paramNamedValidModelAttr
));
}
@Test
public
void
resovleArgumentFromModel
()
throws
Exception
{
getAttributeFromModel
(
"attrName"
,
paramNamedValidModelAttr
);
getAttributeFromModel
(
"testBean"
,
paramModelAttr
);
getAttributeFromModel
(
"testBean"
,
paramNonSimpleType
);
}
private
void
getAttributeFromModel
(
String
expectedAttributeName
,
MethodParameter
param
)
throws
Exception
{
Object
target
=
new
TestBean
();
mavContainer
.
addAttribute
(
expectedAttributeName
,
target
);
WebDataBinder
dataBinder
=
new
WebRequestDataBinder
(
target
);
WebDataBinderFactory
factory
=
mock
(
WebDataBinderFactory
.
class
);
given
(
factory
.
createBinder
(
webRequest
,
target
,
expectedAttributeName
)).
willReturn
(
dataBinder
);
processor
.
resolveArgument
(
param
,
mavContainer
,
webRequest
,
factory
);
verify
(
factory
).
createBinder
(
webRequest
,
target
,
expectedAttributeName
);
public
void
resolveArgumentFromModel
()
throws
Exception
{
testGetAttributeFromModel
(
"attrName"
,
this
.
paramNamedValidModelAttr
);
testGetAttributeFromModel
(
"testBean"
,
this
.
paramModelAttr
);
testGetAttributeFromModel
(
"testBean"
,
this
.
paramNonSimpleType
);
}
@Test
public
void
resovleArgumentViaDefaultConstructor
()
throws
Exception
{
WebDataBinder
dataBinder
=
new
WebRequestDataBinder
(
null
);
WebDataBinderFactory
factory
=
mock
(
WebDataBinderFactory
.
class
);
given
(
factory
.
createBinder
(
(
NativeWebRequest
)
anyObject
(),
notNull
(),
eq
(
"attrName"
))).
willReturn
(
dataBinder
);
given
(
factory
.
createBinder
(
anyObject
(),
notNull
(),
eq
(
"attrName"
))).
willReturn
(
dataBinder
);
processor
.
resolveArgument
(
paramNamedValidModelAttr
,
mavContainer
,
webRequest
,
factory
);
verify
(
factory
).
createBinder
((
NativeWebRequest
)
anyObject
(),
notNull
(),
eq
(
"attrName"
));
this
.
processor
.
resolveArgument
(
this
.
paramNamedValidModelAttr
,
this
.
container
,
this
.
request
,
factory
);
verify
(
factory
).
createBinder
(
anyObject
(),
notNull
(),
eq
(
"attrName"
));
}
@Test
public
void
resolveArgumentValidation
()
throws
Exception
{
String
name
=
"attrName"
;
Object
target
=
new
TestBean
();
mavC
ontainer
.
addAttribute
(
name
,
target
);
this
.
c
ontainer
.
addAttribute
(
name
,
target
);
StubRequestDataBinder
dataBinder
=
new
StubRequestDataBinder
(
target
,
name
);
WebDataBinderFactory
binderF
actory
=
mock
(
WebDataBinderFactory
.
class
);
given
(
binderFactory
.
createBinder
(
webR
equest
,
target
,
name
)).
willReturn
(
dataBinder
);
WebDataBinderFactory
f
actory
=
mock
(
WebDataBinderFactory
.
class
);
given
(
factory
.
createBinder
(
this
.
r
equest
,
target
,
name
)).
willReturn
(
dataBinder
);
processor
.
resolveArgument
(
paramNamedValidModelAttr
,
mavContainer
,
webRequest
,
binderF
actory
);
this
.
processor
.
resolveArgument
(
this
.
paramNamedValidModelAttr
,
this
.
container
,
this
.
request
,
f
actory
);
assertTrue
(
dataBinder
.
isBindInvoked
());
assertTrue
(
dataBinder
.
isValidateInvoked
());
}
@Test
(
expected
=
BindException
.
class
)
public
void
reso
vl
eArgumentBindException
()
throws
Exception
{
public
void
reso
lv
eArgumentBindException
()
throws
Exception
{
String
name
=
"testBean"
;
Object
target
=
new
TestBean
();
mavC
ontainer
.
getModel
().
addAttribute
(
target
);
this
.
c
ontainer
.
getModel
().
addAttribute
(
target
);
StubRequestDataBinder
dataBinder
=
new
StubRequestDataBinder
(
target
,
name
);
dataBinder
.
getBindingResult
().
reject
(
"error"
);
WebDataBinderFactory
binderFactory
=
mock
(
WebDataBinderFactory
.
class
);
given
(
binderFactory
.
createBinder
(
webR
equest
,
target
,
name
)).
willReturn
(
dataBinder
);
given
(
binderFactory
.
createBinder
(
this
.
r
equest
,
target
,
name
)).
willReturn
(
dataBinder
);
processor
.
resolveArgument
(
paramNonSimpleType
,
mavContainer
,
webR
equest
,
binderFactory
);
verify
(
binderFactory
).
createBinder
(
webR
equest
,
target
,
name
);
this
.
processor
.
resolveArgument
(
this
.
paramNonSimpleType
,
this
.
container
,
this
.
r
equest
,
binderFactory
);
verify
(
binderFactory
).
createBinder
(
this
.
r
equest
,
target
,
name
);
}
@Test
// SPR-9378
public
void
resolveArgumentOrdering
()
throws
Exception
{
String
name
=
"testBean"
;
Object
testBean
=
new
TestBean
(
name
);
mavC
ontainer
.
addAttribute
(
name
,
testBean
);
mavC
ontainer
.
addAttribute
(
BindingResult
.
MODEL_KEY_PREFIX
+
name
,
testBean
);
this
.
c
ontainer
.
addAttribute
(
name
,
testBean
);
this
.
c
ontainer
.
addAttribute
(
BindingResult
.
MODEL_KEY_PREFIX
+
name
,
testBean
);
Object
anotherTestBean
=
new
TestBean
();
mavC
ontainer
.
addAttribute
(
"anotherTestBean"
,
anotherTestBean
);
this
.
c
ontainer
.
addAttribute
(
"anotherTestBean"
,
anotherTestBean
);
StubRequestDataBinder
dataBinder
=
new
StubRequestDataBinder
(
testBean
,
name
);
WebDataBinderFactory
binderFactory
=
mock
(
WebDataBinderFactory
.
class
);
given
(
binderFactory
.
createBinder
(
webR
equest
,
testBean
,
name
)).
willReturn
(
dataBinder
);
given
(
binderFactory
.
createBinder
(
this
.
r
equest
,
testBean
,
name
)).
willReturn
(
dataBinder
);
processor
.
resolveArgument
(
paramModelAttr
,
mavContainer
,
webR
equest
,
binderFactory
);
this
.
processor
.
resolveArgument
(
this
.
paramModelAttr
,
this
.
container
,
this
.
r
equest
,
binderFactory
);
assertSame
(
"Resolved attribute should be updated to be last in the order"
,
testBean
,
mavContainer
.
getModel
().
values
().
toArray
()[
1
]);
assertSame
(
"BindingResult of resolved attribute should be last in the order"
,
dataBinder
.
getBindingResult
(),
mavContainer
.
getModel
().
values
().
toArray
()[
2
]);
Object
[]
values
=
this
.
container
.
getModel
().
values
().
toArray
();
assertSame
(
"Resolved attribute should be updated to be last"
,
testBean
,
values
[
1
]);
assertSame
(
"BindingResult of resolved attr should be last"
,
dataBinder
.
getBindingResult
(),
values
[
2
]);
}
@Test
public
void
handleAnnotatedReturnValue
()
throws
Exception
{
processor
.
handleReturnValue
(
"expected"
,
returnParamNamedModelAttr
,
mavContainer
,
webR
equest
);
assertEquals
(
"expected"
,
mavC
ontainer
.
getModel
().
get
(
"modelAttrName"
));
this
.
processor
.
handleReturnValue
(
"expected"
,
this
.
returnParamNamedModelAttr
,
this
.
container
,
this
.
r
equest
);
assertEquals
(
"expected"
,
this
.
c
ontainer
.
getModel
().
get
(
"modelAttrName"
));
}
@Test
public
void
handleNotAnnotatedReturnValue
()
throws
Exception
{
TestBean
testBean
=
new
TestBean
(
"expected"
);
processor
.
handleReturnValue
(
testBean
,
returnParamNonSimpleType
,
mavContainer
,
webRequest
);
this
.
processor
.
handleReturnValue
(
testBean
,
this
.
returnParamNonSimpleType
,
this
.
container
,
this
.
request
);
assertSame
(
testBean
,
this
.
container
.
getModel
().
get
(
"testBean"
));
}
private
void
testGetAttributeFromModel
(
String
expectedAttrName
,
MethodParameter
param
)
throws
Exception
{
Object
target
=
new
TestBean
();
this
.
container
.
addAttribute
(
expectedAttrName
,
target
);
assertSame
(
testBean
,
mavContainer
.
getModel
().
get
(
"testBean"
));
WebDataBinder
dataBinder
=
new
WebRequestDataBinder
(
target
);
WebDataBinderFactory
factory
=
mock
(
WebDataBinderFactory
.
class
);
given
(
factory
.
createBinder
(
this
.
request
,
target
,
expectedAttrName
)).
willReturn
(
dataBinder
);
this
.
processor
.
resolveArgument
(
param
,
this
.
container
,
this
.
request
,
factory
);
verify
(
factory
).
createBinder
(
this
.
request
,
target
,
expectedAttrName
);
}
...
...
@@ -246,6 +236,7 @@ public class ModelAttributeMethodProcessorTests {
private
boolean
validateInvoked
;
public
StubRequestDataBinder
(
Object
target
,
String
objectName
)
{
super
(
target
,
objectName
);
}
...
...
@@ -285,13 +276,17 @@ public class ModelAttributeMethodProcessorTests {
private
static
class
ModelAttributeHandler
{
@SuppressWarnings
(
"unused"
)
public
void
modelAttribute
(
@ModelAttribute
(
"attrName"
)
@Valid
TestBean
annotatedAttr
,
Errors
errors
,
int
intArg
,
@ModelAttribute
TestBean
defaultNameAttr
,
TestBean
notAnnotatedAttr
)
{
public
void
modelAttribute
(
@ModelAttribute
(
"attrName"
)
@Valid
TestBean
annotatedAttr
,
Errors
errors
,
int
intArg
,
@ModelAttribute
TestBean
defaultNameAttr
,
TestBean
notAnnotatedAttr
)
{
}
}
@ModelAttribute
(
"modelAttrName"
)
@ModelAttribute
(
"modelAttrName"
)
@SuppressWarnings
(
"unused"
)
private
String
annotatedReturnValue
()
{
return
null
;
}
...
...
spring-web/src/test/java/org/springframework/web/method/annotation/ModelFactoryTests.java
浏览文件 @
806e79b1
/*
* Copyright 2002-201
4
the original author or authors.
* Copyright 2002-201
6
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.
...
...
@@ -16,19 +16,12 @@
package
org.springframework.web.method.annotation
;
import
static
org
.
junit
.
Assert
.
assertEquals
;
import
static
org
.
junit
.
Assert
.
assertNull
;
import
static
org
.
junit
.
Assert
.
assertSame
;
import
static
org
.
junit
.
Assert
.
assertTrue
;
import
static
org
.
junit
.
Assert
.
fail
;
import
static
org
.
mockito
.
BDDMockito
.
given
;
import
static
org
.
mockito
.
BDDMockito
.
mock
;
import
java.lang.reflect.Method
;
import
java.util.
Array
s
;
import
java.util.
Collection
s
;
import
org.junit.Before
;
import
org.junit.Test
;
import
org.springframework.core.LocalVariableTableParameterNameDiscoverer
;
import
org.springframework.mock.web.test.MockHttpServletRequest
;
import
org.springframework.ui.Model
;
...
...
@@ -43,10 +36,19 @@ import org.springframework.web.bind.support.SessionAttributeStore;
import
org.springframework.web.bind.support.WebDataBinderFactory
;
import
org.springframework.web.context.request.NativeWebRequest
;
import
org.springframework.web.context.request.ServletWebRequest
;
import
org.springframework.web.method.HandlerMethod
;
import
org.springframework.web.method.support.HandlerMethodArgumentResolverComposite
;
import
org.springframework.web.method.support.InvocableHandlerMethod
;
import
org.springframework.web.method.support.ModelAndViewContainer
;
import
static
org
.
junit
.
Assert
.
assertEquals
;
import
static
org
.
junit
.
Assert
.
assertNull
;
import
static
org
.
junit
.
Assert
.
assertSame
;
import
static
org
.
junit
.
Assert
.
assertTrue
;
import
static
org
.
junit
.
Assert
.
fail
;
import
static
org
.
mockito
.
BDDMockito
.
given
;
import
static
org
.
mockito
.
BDDMockito
.
mock
;
/**
* Text fixture for {@link ModelFactory} tests.
...
...
@@ -55,103 +57,92 @@ import org.springframework.web.method.support.ModelAndViewContainer;
*/
public
class
ModelFactoryTests
{
private
TestController
controller
=
new
TestController
();
private
InvocableHandlerMethod
handleMethod
;
private
NativeWebRequest
webRequest
;
private
InvocableHandlerMethod
handleSessionAttrMethod
;
private
SessionAttributesHandler
attributeHandler
;
private
SessionAttribute
sHandler
sessionAttrsHandler
;
private
SessionAttribute
Store
attributeStore
;
private
SessionAttributeStore
sessionAttributeStore
;
private
TestController
controller
=
new
TestController
()
;
private
NativeWebRequest
webRequest
;
private
ModelAndViewContainer
mavContainer
;
@Before
public
void
setUp
()
throws
Exception
{
this
.
controller
=
new
TestController
();
Method
method
=
TestController
.
class
.
getDeclaredMethod
(
"handle"
);
this
.
handleMethod
=
new
InvocableHandlerMethod
(
this
.
controller
,
method
);
method
=
TestController
.
class
.
getDeclaredMethod
(
"handleSessionAttr"
,
String
.
class
);
this
.
handleSessionAttrMethod
=
new
InvocableHandlerMethod
(
this
.
controller
,
method
);
this
.
sessionAttributeStore
=
new
DefaultSessionAttributeStore
();
this
.
sessionAttrsHandler
=
new
SessionAttributesHandler
(
TestController
.
class
,
this
.
sessionAttributeStore
);
this
.
webRequest
=
new
ServletWebRequest
(
new
MockHttpServletRequest
());
this
.
attributeStore
=
new
DefaultSessionAttributeStore
();
this
.
attributeHandler
=
new
SessionAttributesHandler
(
TestController
.
class
,
this
.
attributeStore
);
this
.
controller
=
new
TestController
();
this
.
mavContainer
=
new
ModelAndViewContainer
();
}
@Test
public
void
modelAttributeMethod
()
throws
Exception
{
ModelFactory
modelFactory
=
createModelFactory
(
"modelAttr"
,
Model
.
class
);
ModelAndViewContainer
mavContainer
=
new
ModelAndViewContainer
(
);
modelFactory
.
initModel
(
this
.
webRequest
,
mavContainer
,
this
.
handle
Method
);
HandlerMethod
handlerMethod
=
createHandlerMethod
(
"handle"
);
modelFactory
.
initModel
(
this
.
webRequest
,
this
.
mavContainer
,
handler
Method
);
assertEquals
(
Boolean
.
TRUE
,
mavContainer
.
getModel
().
get
(
"modelAttr"
));
assertEquals
(
Boolean
.
TRUE
,
this
.
mavContainer
.
getModel
().
get
(
"modelAttr"
));
}
@Test
public
void
modelAttributeMethodWithExplicitName
()
throws
Exception
{
ModelFactory
modelFactory
=
createModelFactory
(
"modelAttrWithName"
);
ModelAndViewContainer
mavContainer
=
new
ModelAndViewContainer
(
);
modelFactory
.
initModel
(
this
.
webRequest
,
mavContainer
,
this
.
handle
Method
);
HandlerMethod
handlerMethod
=
createHandlerMethod
(
"handle"
);
modelFactory
.
initModel
(
this
.
webRequest
,
this
.
mavContainer
,
handler
Method
);
assertEquals
(
Boolean
.
TRUE
,
mavContainer
.
getModel
().
get
(
"name"
));
assertEquals
(
Boolean
.
TRUE
,
this
.
mavContainer
.
getModel
().
get
(
"name"
));
}
@Test
public
void
modelAttributeMethodWithNameByConvention
()
throws
Exception
{
ModelFactory
modelFactory
=
createModelFactory
(
"modelAttrConvention"
);
ModelAndViewContainer
mavContainer
=
new
ModelAndViewContainer
(
);
modelFactory
.
initModel
(
this
.
webRequest
,
mavContainer
,
this
.
handle
Method
);
HandlerMethod
handlerMethod
=
createHandlerMethod
(
"handle"
);
modelFactory
.
initModel
(
this
.
webRequest
,
this
.
mavContainer
,
handler
Method
);
assertEquals
(
Boolean
.
TRUE
,
mavContainer
.
getModel
().
get
(
"boolean"
));
assertEquals
(
Boolean
.
TRUE
,
this
.
mavContainer
.
getModel
().
get
(
"boolean"
));
}
@Test
public
void
modelAttributeMethodWithNullReturnValue
()
throws
Exception
{
ModelFactory
modelFactory
=
createModelFactory
(
"nullModelAttr"
);
ModelAndViewContainer
mavContainer
=
new
ModelAndViewContainer
(
);
modelFactory
.
initModel
(
this
.
webRequest
,
mavContainer
,
this
.
handle
Method
);
HandlerMethod
handlerMethod
=
createHandlerMethod
(
"handle"
);
modelFactory
.
initModel
(
this
.
webRequest
,
this
.
mavContainer
,
handler
Method
);
assertTrue
(
mavContainer
.
containsAttribute
(
"name"
));
assertNull
(
mavContainer
.
getModel
().
get
(
"name"
));
assertTrue
(
this
.
mavContainer
.
containsAttribute
(
"name"
));
assertNull
(
this
.
mavContainer
.
getModel
().
get
(
"name"
));
}
@Test
public
void
sessionAttribute
()
throws
Exception
{
this
.
sessionAttributeStore
.
storeAttribute
(
this
.
webRequest
,
"sessionAttr"
,
"sessionAttrValue"
);
// Resolve successfully handler session attribute once
assertTrue
(
sessionAttrsHandler
.
isHandlerSessionAttribute
(
"sessionAttr"
,
null
));
this
.
attributeStore
.
storeAttribute
(
this
.
webRequest
,
"sessionAttr"
,
"sessionAttrValue"
);
ModelFactory
modelFactory
=
createModelFactory
(
"modelAttr"
,
Model
.
class
);
ModelAndViewContainer
mavContainer
=
new
ModelAndViewContainer
(
);
modelFactory
.
initModel
(
this
.
webRequest
,
mavContainer
,
this
.
handle
Method
);
HandlerMethod
handlerMethod
=
createHandlerMethod
(
"handle"
);
modelFactory
.
initModel
(
this
.
webRequest
,
this
.
mavContainer
,
handler
Method
);
assertEquals
(
"sessionAttrValue"
,
mavContainer
.
getModel
().
get
(
"sessionAttr"
));
assertEquals
(
"sessionAttrValue"
,
this
.
mavContainer
.
getModel
().
get
(
"sessionAttr"
));
}
@Test
public
void
sessionAttributeNotPresent
()
throws
Exception
{
ModelFactory
modelFactory
=
new
ModelFactory
(
null
,
null
,
this
.
sessionAttrs
Handler
);
ModelFactory
modelFactory
=
new
ModelFactory
(
null
,
null
,
this
.
attribute
Handler
);
HandlerMethod
handlerMethod
=
createHandlerMethod
(
"handleSessionAttr"
,
String
.
class
);
try
{
modelFactory
.
initModel
(
this
.
webRequest
,
new
ModelAndViewContainer
(),
this
.
handleSessionAtt
rMethod
);
modelFactory
.
initModel
(
this
.
webRequest
,
this
.
mavContainer
,
handle
rMethod
);
fail
(
"Expected HttpSessionRequiredException"
);
}
catch
(
HttpSessionRequiredException
e
)
{
// expected
}
this
.
sessionAttributeStore
.
storeAttribute
(
this
.
webRequest
,
"sessionAttr"
,
"sessionAttrValue"
);
ModelAndViewContainer
mavContainer
=
new
ModelAndViewContainer
();
modelFactory
.
initModel
(
this
.
webRequest
,
mavContainer
,
this
.
handleSessionAttrMethod
);
// Now add attribute and try again
this
.
attributeStore
.
storeAttribute
(
this
.
webRequest
,
"sessionAttr"
,
"sessionAttrValue"
);
assertEquals
(
"sessionAttrValue"
,
mavContainer
.
getModel
().
get
(
"sessionAttr"
));
modelFactory
.
initModel
(
this
.
webRequest
,
this
.
mavContainer
,
handlerMethod
);
assertEquals
(
"sessionAttrValue"
,
this
.
mavContainer
.
getModel
().
get
(
"sessionAttr"
));
}
@Test
...
...
@@ -165,11 +156,12 @@ public class ModelFactoryTests {
WebDataBinderFactory
binderFactory
=
mock
(
WebDataBinderFactory
.
class
);
given
(
binderFactory
.
createBinder
(
this
.
webRequest
,
command
,
commandName
)).
willReturn
(
dataBinder
);
ModelFactory
modelFactory
=
new
ModelFactory
(
null
,
binderFactory
,
this
.
sessionAttrs
Handler
);
ModelFactory
modelFactory
=
new
ModelFactory
(
null
,
binderFactory
,
this
.
attribute
Handler
);
modelFactory
.
updateModel
(
this
.
webRequest
,
container
);
assertEquals
(
command
,
container
.
getModel
().
get
(
commandName
));
assertSame
(
dataBinder
.
getBindingResult
(),
container
.
getModel
().
get
(
bindingResultKey
(
commandName
)));
String
bindingResultKey
=
BindingResult
.
MODEL_KEY_PREFIX
+
commandName
;
assertSame
(
dataBinder
.
getBindingResult
(),
container
.
getModel
().
get
(
bindingResultKey
));
assertEquals
(
2
,
container
.
getModel
().
size
());
}
...
...
@@ -184,11 +176,11 @@ public class ModelFactoryTests {
WebDataBinderFactory
binderFactory
=
mock
(
WebDataBinderFactory
.
class
);
given
(
binderFactory
.
createBinder
(
this
.
webRequest
,
attribute
,
attributeName
)).
willReturn
(
dataBinder
);
ModelFactory
modelFactory
=
new
ModelFactory
(
null
,
binderFactory
,
this
.
sessionAttrs
Handler
);
ModelFactory
modelFactory
=
new
ModelFactory
(
null
,
binderFactory
,
this
.
attribute
Handler
);
modelFactory
.
updateModel
(
this
.
webRequest
,
container
);
assertEquals
(
attribute
,
container
.
getModel
().
get
(
attributeName
));
assertEquals
(
attribute
,
this
.
sessionA
ttributeStore
.
retrieveAttribute
(
this
.
webRequest
,
attributeName
));
assertEquals
(
attribute
,
this
.
a
ttributeStore
.
retrieveAttribute
(
this
.
webRequest
,
attributeName
));
}
@Test
...
...
@@ -198,9 +190,7 @@ public class ModelFactoryTests {
ModelAndViewContainer
container
=
new
ModelAndViewContainer
();
container
.
addAttribute
(
attributeName
,
attribute
);
// Store and resolve once (to be "remembered")
this
.
sessionAttributeStore
.
storeAttribute
(
this
.
webRequest
,
attributeName
,
attribute
);
this
.
sessionAttrsHandler
.
isHandlerSessionAttribute
(
attributeName
,
null
);
this
.
attributeStore
.
storeAttribute
(
this
.
webRequest
,
attributeName
,
attribute
);
WebDataBinder
dataBinder
=
new
WebDataBinder
(
attribute
,
attributeName
);
WebDataBinderFactory
binderFactory
=
mock
(
WebDataBinderFactory
.
class
);
...
...
@@ -208,11 +198,11 @@ public class ModelFactoryTests {
container
.
getSessionStatus
().
setComplete
();
ModelFactory
modelFactory
=
new
ModelFactory
(
null
,
binderFactory
,
this
.
sessionAttrs
Handler
);
ModelFactory
modelFactory
=
new
ModelFactory
(
null
,
binderFactory
,
this
.
attribute
Handler
);
modelFactory
.
updateModel
(
this
.
webRequest
,
container
);
assertEquals
(
attribute
,
container
.
getModel
().
get
(
attributeName
));
assertNull
(
this
.
sessionA
ttributeStore
.
retrieveAttribute
(
this
.
webRequest
,
attributeName
));
assertNull
(
this
.
a
ttributeStore
.
retrieveAttribute
(
this
.
webRequest
,
attributeName
));
}
// SPR-12542
...
...
@@ -233,33 +223,33 @@ public class ModelFactoryTests {
WebDataBinderFactory
binderFactory
=
mock
(
WebDataBinderFactory
.
class
);
given
(
binderFactory
.
createBinder
(
this
.
webRequest
,
attribute
,
attributeName
)).
willReturn
(
dataBinder
);
ModelFactory
modelFactory
=
new
ModelFactory
(
null
,
binderFactory
,
this
.
sessionAttrs
Handler
);
ModelFactory
modelFactory
=
new
ModelFactory
(
null
,
binderFactory
,
this
.
attribute
Handler
);
modelFactory
.
updateModel
(
this
.
webRequest
,
container
);
assertEquals
(
queryParam
,
container
.
getModel
().
get
(
queryParamName
));
assertEquals
(
1
,
container
.
getModel
().
size
());
assertEquals
(
attribute
,
this
.
sessionA
ttributeStore
.
retrieveAttribute
(
this
.
webRequest
,
attributeName
));
assertEquals
(
attribute
,
this
.
a
ttributeStore
.
retrieveAttribute
(
this
.
webRequest
,
attributeName
));
}
private
String
bindingResultKey
(
String
key
)
{
return
BindingResult
.
MODEL_KEY_PREFIX
+
key
;
}
private
ModelFactory
createModelFactory
(
String
methodName
,
Class
<?>...
parameterTypes
)
throws
Exception
{
Method
method
=
TestController
.
class
.
getMethod
(
methodName
,
parameterTypes
);
private
ModelFactory
createModelFactory
(
String
methodName
,
Class
<?>...
parameterTypes
)
throws
Exception
{
HandlerMethodArgumentResolverComposite
resolvers
=
new
HandlerMethodArgumentResolverComposite
();
resolvers
.
addResolver
(
new
ModelMethodProcessor
());
HandlerMethodArgumentResolverComposite
argResolvers
=
new
HandlerMethodArgumentResolverComposite
();
argResolvers
.
addResolver
(
new
ModelMethodProcessor
());
InvocableHandlerMethod
modelMethod
=
createHandlerMethod
(
methodName
,
parameterTypes
);
modelMethod
.
setHandlerMethodArgumentResolvers
(
resolvers
);
modelMethod
.
setDataBinderFactory
(
null
);
modelMethod
.
setParameterNameDiscoverer
(
new
LocalVariableTableParameterNameDiscoverer
());
InvocableHandlerMethod
handlerMethod
=
new
InvocableHandlerMethod
(
this
.
controller
,
method
);
handlerMethod
.
setHandlerMethodArgumentResolvers
(
argResolvers
);
handlerMethod
.
setDataBinderFactory
(
null
);
handlerMethod
.
setParameterNameDiscoverer
(
new
LocalVariableTableParameterNameDiscoverer
());
return
new
ModelFactory
(
Collections
.
singletonList
(
modelMethod
),
null
,
this
.
attributeHandler
);
}
return
new
ModelFactory
(
Arrays
.
asList
(
handlerMethod
),
null
,
this
.
sessionAttrsHandler
);
private
InvocableHandlerMethod
createHandlerMethod
(
String
methodName
,
Class
<?>...
paramTypes
)
throws
Exception
{
Method
method
=
this
.
controller
.
getClass
().
getMethod
(
methodName
,
paramTypes
);
return
new
InvocableHandlerMethod
(
this
.
controller
,
method
);
}
@SessionAttributes
(
"sessionAttr"
)
@SuppressWarnings
(
"unused"
)
private
static
class
TestController
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录