SpringMVC中自定义参数解析器及内置类型的绑定
@RequestMapping("paramTest")
@ResponseBody
public Object paramTest(HttpServletRequest request){
User user = (User) request.getAttribute("user");
System.out.println(user);
return "ok";
}
这样的方式显然有一些麻烦,最好可以达到下面的效果 @RequestMapping("paramTest")
@ResponseBody
public Object paramTest(User user){
System.out.println(user);
return "ok";
}
这样一来,就方便了好多。有人可能会有些怀疑,不就是少了一行代码吗,这里只是举一个简单的例子,如果现实中需要成百上千行的代码来构造这个User呢?那么构造这个User的逻辑就可以封装在自定义的参数解析器中。public class UserArgumentResolver implements HandlerMethodArgumentResolver {
@Override
public boolean supportsParameter(MethodParameter parameter) {
if (parameter.getParameterType().equals(User.class)) {
return true;
}
return false;
}
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
return webRequest.getAttribute("user", RequestAttributes.SCOPE_REQUEST);
}
}
它的第一个方法用于匹配参数的类型,如果是User类型,则用第二个方法解析出一个User对象返回。然后还需要把这个参数解析器注册到HandlerAdapter中,像下面这样: <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<property name="customArgumentResolvers">
<list>
<bean class="com.ebaoyang.controller.resolver.UserArgumentResolver" />
</list>
</property>
<property name="order" value="0" />
</bean>
通过上面的配置就可以实现自定义类型User的绑定,可以在HandlerMethod中直接使用。 public boolean supportsParameter(MethodParameter parameter) {
Class<?> paramType = parameter.getParameterType();
return WebRequest.class.isAssignableFrom(paramType) ||
ServletRequest.class.isAssignableFrom(paramType) ||
MultipartRequest.class.isAssignableFrom(paramType) ||
HttpSession.class.isAssignableFrom(paramType) ||
Principal.class.isAssignableFrom(paramType) ||
Locale.class.equals(paramType) ||
InputStream.class.isAssignableFrom(paramType) ||
Reader.class.isAssignableFrom(paramType);
}
这些类型的参数的绑定方法见resolveArgument方法: public Object resolveArgument(
MethodParameter parameter, ModelAndViewContainer mavContainer,
NativeWebRequest webRequest, WebDataBinderFactory binderFactory)
throws IOException {
Class<?> paramType = parameter.getParameterType();
if (WebRequest.class.isAssignableFrom(paramType)) {
return webRequest;
}
HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class);
if (ServletRequest.class.isAssignableFrom(paramType) || MultipartRequest.class.isAssignableFrom(paramType)) {
Object nativeRequest = webRequest.getNativeRequest(paramType);
if (nativeRequest == null) {
throw new IllegalStateException(
"Current request is not of type [" + paramType.getName() + "]: " + request);
}
return nativeRequest;
}
else if (HttpSession.class.isAssignableFrom(paramType)) {
return request.getSession();
}
else if (Principal.class.isAssignableFrom(paramType)) {
return request.getUserPrincipal();
}
else if (Locale.class.equals(paramType)) {
return RequestContextUtils.getLocale(request);
}
else if (InputStream.class.isAssignableFrom(paramType)) {
return request.getInputStream();
}
else if (Reader.class.isAssignableFrom(paramType)) {
return request.getReader();
}
else {
// should never happen..
Method method = parameter.getMethod();
throw new UnsupportedOperationException("Unknown parameter type: " + paramType + " in method: " + method);
}
}
三,一般类型参数的绑定