springMVC 之 HandlerMethodArgumentResolver使用
我们使用springMVC 的 controller的方法时需要获取ServletHttpRequest对象的时候直接在方法参数列表里写上 ServletHttpRequest request框架就直接给注入进来了,但是这是怎么实现的呢?经过查看spring源码发现有这么一个接口HandlerMethodArgumentResolver,
顾名思义就是 方法参数解析的接口(中式翻译~~ 哈哈),接口里有两个方法 分别是是否支持解析 和 解析参数的方法。
看一下它的各个实现类发现
其中有一个 ServletRequestMethodArgumentResolver 类 ,查看其源码,可以看到他支持注入的参数类型和对应类型的参数解析代码,可以看到支持的参数类型里有 ServletRequest 接口,所以自然支持ServletHttpRequest 类型
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
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 (HttpMethod.class == paramType) {
return ((ServletWebRequest) webRequest).getHttpMethod();
}
else if (Principal.class.isAssignableFrom(paramType)) {
return request.getUserPrincipal();
}
else if (Locale.class == paramType) {
return RequestContextUtils.getLocale(request);
}
else if (TimeZone.class == paramType) {
TimeZone timeZone = RequestContextUtils.getTimeZone(request);
return (timeZone != null ? timeZone : TimeZone.getDefault());
}
else if ("java.time.ZoneId".equals(paramType.getName())) {
return ZoneIdResolver.resolveZoneId(request);
}
else if (InputStream.class.isAssignableFrom(paramType)) {
return request.getInputStream();
}
else if (Reader.class.isAssignableFrom(paramType)) {
return request.getReader();
}
else {
// should never happen...
throw new UnsupportedOperationException(
"Unknown parameter type: " + paramType + " in method: " + parameter.getMethod());
}
}
更深层次的代码下次补上 :)
知道了这个接口之后我们就可以自定义一些参数解析器,例如在方法参数获取当前登录用户的解析器等。