您的位置:首页 > 编程语言 > Java开发

springMVC使用HandlerMethodArgumentResolver 自定义解析器实现请求参数绑定方法参数

2016-06-15 15:39 806 查看
转载自:http://blog.csdn.net/truong/article/details/30971317

平时工作用是struts2,近来试了下springMVC,感觉很方便。

然后遇到了问题:

我有Person和Cat两个类,他们都有name这个field,如果我有一个Controller的方法接收Cat和Person两个参数,我应该如何分别他们的name?

话说在页面写person.name和cat.name是没什么意义的,于是我看了一下stackOverFlow。

有人推荐我写一个类,并给这个类里增加Person和Cat类型的变量,这样就可以在页面里写person.name和cat.name以作区分了。

虽然解决问题,但并不高雅。

于是我找到了另一个方法——给method参数加annotation,使用HandlerMethodArgumentResolver。

那就顺便说说HandlerMethodArgumentResolver。

 

springMVC有这样一个类:

org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter

view
sourceprint?

01.
/**


02.
*
An {@link AbstractHandlerMethodAdapter} that supports {@link HandlerMethod}s


03.
*
with the signature -- method argument and return types, defined in


04.
*
{@code @RequestMapping}.


05.
*


06.
*
<p>Support for custom argument and return value types can be added via


07.
*
{@link #setCustomArgumentResolvers} and {@link #setCustomReturnValueHandlers}.


08.
*
Or alternatively to re-configure all argument and return value types use


09.
*
{@link #setArgumentResolvers} and {@link #setReturnValueHandlers(List)}.


10.
*


11.
*
@author Rossen Stoyanchev


12.
*
@since 3.1


13.
*
@see HandlerMethodArgumentResolver


14.
*
@see HandlerMethodReturnValueHandler


15.
*/


16.
public
 
class
 
RequestMappingHandlerAdapter 
extends
 
AbstractHandlerMethodAdapter 
implements
 
BeanFactoryAware,


17.
InitializingBean


看了说明大致明白,他可以用来定制method参数和返回值。

我这里需要修改的是参数,也就是需要用他的setCustomArgumentResolvers方法。

 

view
sourceprint?

1.
/**


2.
*
Provide resolvers for custom argument types. Custom resolvers are ordered


3.
*
after built-in ones. To override the built-in support for argument


4.
*
resolution use {@link #setArgumentResolvers} instead.


5.
*/


6.
public
 
void
 
setCustomArgumentResolvers(List<HandlerMethodArgumentResolver>
argumentResolvers) {


7.
this
.customArgumentResolvers
= argumentResolvers;


8.
}


参数List类型的泛型是HandlerMethodArgumentResolver,我需要有一个类去实现他。

 

view
sourceprint?

01.
import
 
java.lang.reflect.Field;


02.
import
 
java.util.Iterator;


03.
import
 
org.springframework.beans.BeanUtils;


04.
import
 
org.springframework.core.MethodParameter;


05.
import
 
org.springframework.web.bind.support.WebDataBinderFactory;


06.
import
 
org.springframework.web.context.request.NativeWebRequest;


07.
import
 
org.springframework.web.method.support.HandlerMethodArgumentResolver;


08.
import
 
org.springframework.web.method.support.ModelAndViewContainer;


09.
import
 
pac.ano.FormModel;


10.
public
 
class
 
MyMethodArgumentsResolver 
implements
 
HandlerMethodArgumentResolver
{


11.
 

12.
public
 
boolean
 
supportsParameter(MethodParameter
parameter) {


13.
return
 
parameter.hasParameterAnnotation(FormModel.
class
);


14.
}


15.
public
 
Object
resolveArgument(MethodParameter parameter,


16.
ModelAndViewContainer
mavContainer, NativeWebRequest webRequest,


17.
WebDataBinderFactory
binderFactory) 
throws
 
Exception
{


18.
String
objName = parameter.getParameterName() + 
"."
;


19.
Object
o = BeanUtils.instantiate(parameter.getParameterType());


20.
StringBuffer
tmp;


21.
String[]
val;


22.
Field[]
frr = parameter.getParameterType().getDeclaredFields();


23.
for
 
(Iterator<String>
itr = webRequest.getParameterNames(); itr


24.
.hasNext();)
{


25.
tmp
= 
new
 
StringBuffer(itr.next());


26.
if
 
(tmp.indexOf(objName)
< 
0
)
continue
;


27.
for
 
(
int
 
i
= 
0
;
i < frr.length; i++) {


28.
frr[i].setAccessible(
true
);


29.
if
 
(tmp.toString().equals(objName
+ frr[i].getName())) {


30.
val
= webRequest.getParameterValues(tmp.toString());


31.
frr[i].set(o,
val[
0
]);


32.
}


33.
}


34.
}


35.
return
 
o;


36.
}


37.
}


这是一个不完整的版本,但是用来做例子是足够了。

我可以在supportsParameter里判断参数是否满足我的Resolver。

而在resolveArgument里我们可以处理这些参数。

另外,FormModel就是我创建的annotation。

 

view
sourceprint?

01.
import
 
java.lang.annotation.Documented;


02.
import
 
java.lang.annotation.ElementType;


03.
import
 
java.lang.annotation.Retention;


04.
import
 
java.lang.annotation.RetentionPolicy;


05.
import
 
java.lang.annotation.Target;


06.
@Target
({
ElementType.PARAMETER })


07.
@Retention
(RetentionPolicy.RUNTIME)


08.
@Documented


09.
public
 
@interface
 
FormModel
{


10.
String
value();


11.
}


另外,我需要将他配置到spring context中。

 

view
sourceprint?

1.
<
bean
 
class
=
"org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"
>


2.
<
property
 
name
=
"synchronizeOnSession"
 
value
=
"true"
 
/>


3.
<
property
 
name
=
"customArgumentResolvers"
>


4.
<
list
>


5.
<
bean
 
class
=
"pac.ano.interpreter.MyMethodArgumentsResolver"
 
/>


6.
</
list
>


7.
</
property
>


8.
</
bean
>


剩下的就是去使用他,controller中:

 

view
sourceprint?

1.
@RequestMapping
(value=
"/index"
)


2.
public
 
ModelAndView
index(
@FormModel
(
"p"
)Person
p){


3.
ModelAndView
tmpMAV = 
new
 
ModelAndView(
"index"
);


4.
System.out.println(p);


5.
tmpMAV.addObject(
"p.name"
,p.getName());


6.
return
 
tmpMAV;


7.
}


页面中:

 

view
sourceprint?

1.
<
form
 
action
=
"index"
 
method
=
"post"
>


2.
<
input
 
type
=
"text"
 
name
=
"p.name"
 
/>


3.
<
input
 
type
=
"text"
 
name
=
"name"
 
/>


4.
<
input
 
type
=
"text"
 
name
=
"p.age"
 
/>


5.
<
input
 
type
=
"text"
 
name
=
"weight"
 
/>


6.
<
input
 
type
=
"text"
 
name
=
"p.height"
 
/>


7.
<
input
 
type
=
"submit"
 
value
=
"提交"
/>


8.
</
form
>


使用起来很简单,但是要把我需要的功能完全时间就需要多做写工作了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: