平时工作用是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
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方法。
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,我需要有一个类去实现他。
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。
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中。
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中:
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.
}
页面中:
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>
使用起来很简单,但是要把我需要的功能完全时间就需要多做写工作了。

本文详细介绍了如何通过自定义HandlerMethodArgumentResolver解决SpringMVC中参数区分的问题,包括实现步骤、配置方法及其实现案例。
4102

被折叠的 条评论
为什么被折叠?



