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);
}
}
三,一般類型參數的綁定