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

[置顶] SpringMVC从request中获取参数的原理

2017-09-27 19:34 218 查看
servlet原生:将查出的数据放在request、session、application域中

测试代码:

@RequestMapping("/testApi")
public void testApi(HttpServletRequest request, HttpServletResponse response) {
System.out.println(request.getParameter("abc"));
try {
//注意那个CharacterEncodingFilter只是设置了响应的编码格式,
//并没有设置内容类型。所以原生写数据必须使用response.setContentType("text/html");
//解析器解析的响应结果,他会自己设置好一些类型,
//原生直接写,是把他都忽略了。
response.setContentType("text/html");
response.getWriter().write("我是直接写的...");
} catch (IOException e) {
e.printStackTrace();
}
//return "success";
}


地址栏输入:http://localhost/SpringMVC_02_Param_Api/testApi

在DispatherServlet的doDispach方法上打上断点。以Debug模式运行

断点之后进入方法:

DispatcherServlet
//执行目标方法
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());


调用AnnotationMethodHandlerAdapter.handle方法

@Override
public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
...
//执行目标方法
return invokeHandlerMethod(request, response, handler);
}


调用本类的方法。执行目标方法

protected ModelAndView invokeHandlerMethod(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {

//根据handle找到方法解析器
ServletHandlerMethodResolver methodResolver = getMethodResolver(handler);
//获取目标方法
Method handlerMethod = methodResolver.resolveHandlerMethod(request);
//找到方法执行者
ServletHandlerMethodInvoker methodInvoker = new ServletHandlerMethodInvoker(methodResolver);
ServletWebRequest webRequest = new ServletWebRequest(request, response);
ExtendedModelMap implicitModel = new BindingAwareModelMap();

//方法执行者执行目标方法
Object result = methodInvoker.invokeHandlerMethod(handlerMethod, handler, webRequest, implicitModel);
ModelAndView mav =
methodInvoker.getModelAndView(handlerMethod, handler.getClass(), result, implicitModel, webRequest);
methodInvoker.updateModelAttributes(handler, (mav != null ? mav.getModel() : null), implicitModel, webRequest);
return mav;
}


调用HandlerMethodInvoker的invokeHandlerMethod方法。方法执行者执行目标方法

public final Object invokeHandlerMethod(Method handlerMethod, Object handler,
NativeWebRequest webRequest, ExtendedModelMap implicitModel) throws Exception {
Method handlerMethodToInvoke = BridgeMethodResolver.findBridgedMethod(handlerMethod);
...
//解析方法参数
Object[] args = resolveHandlerArguments(handlerMethodToInvoke, handler, webRequest, implicitModel);
...
}


调用本类的resolveHandlerArguments方法。解析方法参数

private Object[] resolveHandlerArguments(Method handlerMethod, Object handler,
NativeWebRequest webRequest, ExtendedModelMap implicitModel) throws Exception {
Class<?>[] paramTypes = handlerMethod.getParameterTypes();
Object[] args = new Object[paramTypes.length];
...
if (annotationsFound == 0) {
//解析细节
Object argValue = resolveCommonArgument(methodParam, webRequest);
if (argValue != WebArgumentResolver.UNRESOLVED) {
args[i] = argValue;
}

...
return args;
}


调用本类的resolveCommonArgument方法。解析的细节

protected Object resolveCommonArgument(MethodParameter methodParameter, NativeWebRequest webRequest)
throws Exception {

// Invoke custom argument resolvers if present...
if (this.customArgumentResolvers != null) {
for (WebArgumentResolver argumentResolver : this.customArgumentResolvers) {
Object value = argumentResolver.resolveArgument(methodParameter, webRequest);
if (value != WebArgumentResolver.UNRESOLVED) {
return value;
}
}
}

// Resolution of standard parameter types...
Class<?> paramType = methodParameter.getParameterType();
//解析标准参数
Object value = resolveStandardArgument(paramType, webRequest);
if (value != WebArgumentResolver.UNRESOLVED && !ClassUtils.isAssignableValue(paramType, value)) {
throw new IllegalStateException("Standard argument type [" + paramType.getName() +
"] resolved to incompatible value of type [" + (value != null ? value.getClass() : null) +
"]. Consider declaring the argument type in a less specific fashion.");
}
return value;
}


调用本类的resolveStandardArgument方法。解析标准参数

@Override
protected Object resolveStandardArgument(Class<?> parameterType, NativeWebRequest webRequest) throws Exception {
HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class);
HttpServletResponse response = webRequest.getNativeResponse(HttpServletResponse.class);

if (ServletRequest.class.isAssignableFrom(parameterType) ||
MultipartRequest.class.isAssignableFrom(parameterType)) {
Object nativeRequest = webRequest.getNativeRequest(parameterType);
if (nativeRequest == null) {
throw new IllegalStateException(
"Current request is not of type [" + parameterType.getName() + "]: " + request);
}
return nativeRequest;
}
else if (ServletResponse.class.isAssignableFrom(parameterType)) {
this.responseArgumentUsed = true;
Object nativeResponse = webRequest.getNativeResponse(parameterType);
if (nativeResponse == null) {
throw new IllegalStateException(
"Current response is not of type [" + parameterType.getName() + "]: " + response);
}
return nativeResponse;
}
else if (HttpSession.class.isAssignableFrom(parameterType)) {
return request.getSession();
}
else if (Principal.class.isAssignableFrom(parameterType)) {
return request.getUserPrincipal();
}
else if (Locale.class.equals(parameterType)) {
return RequestContextUtils.getLocale(request);
}
else if (InputStream.class.isAssignableFrom(parameterType)) {
return request.getInputStream();
}
else if (Reader.class.isAssignableFrom(parameterType)) {
return request.getReader();
}
else if (OutputStream.class.isAssignableFrom(parameterType)) {
this.responseArgumentUsed = true;
return response.getOutputStream();
}
else if (Writer.class.isAssignableFrom(parameterType)) {
this.responseArgumentUsed = true;
return response.getWriter();
}
return super.resolveStandardArgument(parameterType, webRequest);
}


这就是解析HttpServletRequest参数的过程。

通过request.getSession()、request.getUserPrincipal()、 request.getInputStream()、request.getReader()解析参数。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐