SpringMVC从request中获取参数的原理

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()解析参数。

猜你喜欢

转载自blog.csdn.net/OnlyLove_longshao/article/details/78116329