--Test过程:

1. 先执行各种 Filter

2. HttpServlet.service(ServletRequest req, ServletResponse res)

3. HttpServlet.service(HttpServletRequest req, HttpServletResponse resp) 根据 Method做分发。以下是POST流程

4. FrameworkServlet.doPost(HttpServletRequest request, HttpServletResponse response) -> processRequest -> doService -> doDispatch

5. org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handle -> handlerInternal -> invokeHandlerMethod -> invokeHandle -> invokeForRequest -> 

6. InvocableHandlerMethod.doInvoke

7. 到了Action方法

--Post 带参数 详细过程

http://blog.csdn.net/fytain/article/details/43918609

问题:

像普通函数那样定义action。 从 request.body 里的 JSON 串中取出某个属性值。

先解析!

1.  各种Filter

2. /org/apache/catalina/core/ApplicationFilterChain.java 中 internalDoFilter ,servlet.service

3. /javax/servlet/http/HttpServlet.java . service

4. HttpServlet.service(HttpServletRequest req, HttpServletResponse resp) 根据 Method做分发。以下是POST流程

5. FrameworkServlet.doPost(HttpServletRequest request, HttpServletResponse response) -> processRequest -> doService -> doDispatch

6.org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handle -> handlerInternal -> invokeHandlerMethod -> invokeHandle -> invokeForRequest 

7. 在 /org/springframework/web/method/support/InvocableHandlerMethod.java 的 invokeForRequest 方法中:

       getMethodArgumentValues(request, mavContainer , 变参 provideArgs) 获取参数

      之后调用  doInvoke(args)

  getMethodArgumentValue方法:

/**
* Get the method argument values for the current request.
*/
private Object[] getMethodArgumentValues(NativeWebRequest request, ModelAndViewContainer mavContainer,
Object... providedArgs) throws Exception { MethodParameter[] parameters = getMethodParameters();
Object[] args = new Object[parameters.length];
for (int i = 0; i < parameters.length; i++) {
MethodParameter parameter = parameters[i];
parameter.initParameterNameDiscovery(this.parameterNameDiscoverer);
args[i] = resolveProvidedArgument(parameter, providedArgs);
if (args[i] != null) {
continue;
}
if (this.argumentResolvers.supportsParameter(parameter)) {
try {
args[i] = this.argumentResolvers.resolveArgument(
parameter, mavContainer, request, this.dataBinderFactory);
continue;
}
catch (Exception ex) {
if (logger.isDebugEnabled()) {
logger.debug(getArgumentResolutionErrorMessage("Failed to resolve", i), ex);
}
throw ex;
}
}
if (args[i] == null) {
throw new IllegalStateException("Could not resolve method parameter at index " +
parameter.getParameterIndex() + " in " + parameter.getMethod().toGenericString() +
": " + getArgumentResolutionErrorMessage("No suitable resolver for", i));
}
}
return args;
}

重点:

  1. this.argumentResolvers.supportsParameter

  2. this.argumentResolvers.resolveArgument ,如下:

@Override
public final Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception { NamedValueInfo namedValueInfo = getNamedValueInfo(parameter);
MethodParameter nestedParameter = parameter.nestedIfOptional(); Object resolvedName = resolveStringValue(namedValueInfo.name);
if (resolvedName == null) {
throw new IllegalArgumentException(
"Specified name must not resolve to null: [" + namedValueInfo.name + "]");
} Object arg = resolveName(resolvedName.toString(), nestedParameter, webRequest);
if (arg == null) {
if (namedValueInfo.defaultValue != null) {
arg = resolveStringValue(namedValueInfo.defaultValue);
}
else if (namedValueInfo.required && !nestedParameter.isOptional()) {
handleMissingValue(namedValueInfo.name, nestedParameter, webRequest);
}
arg = handleNullValue(namedValueInfo.name, arg, nestedParameter.getNestedParameterType());
}
else if ("".equals(arg) && namedValueInfo.defaultValue != null) {
arg = resolveStringValue(namedValueInfo.defaultValue);
} if (binderFactory != null) {
WebDataBinder binder = binderFactory.createBinder(webRequest, null, namedValueInfo.name);
try {
arg = binder.convertIfNecessary(arg, parameter.getParameterType(), parameter);
}
catch (ConversionNotSupportedException ex) {
throw new MethodArgumentConversionNotSupportedException(arg, ex.getRequiredType(),
namedValueInfo.name, parameter, ex.getCause());
}
catch (TypeMismatchException ex) {
throw new MethodArgumentTypeMismatchException(arg, ex.getRequiredType(),
namedValueInfo.name, parameter, ex.getCause()); }
} handleResolvedValue(arg, namedValueInfo.name, parameter, mavContainer, webRequest); return arg;
}

在 resolveArgument 方法过程中,先执行 resolveName,再执行 handleResolvedValue

@Override
protected Object resolveName(String name, MethodParameter parameter, NativeWebRequest request) throws Exception {
HttpServletRequest servletRequest = request.getNativeRequest(HttpServletRequest.class);
MultipartHttpServletRequest multipartRequest =
WebUtils.getNativeRequest(servletRequest, MultipartHttpServletRequest.class); Object mpArg = MultipartResolutionDelegate.resolveMultipartArgument(name, parameter, servletRequest);
if (mpArg != MultipartResolutionDelegate.UNRESOLVABLE) {
return mpArg;
} Object arg = null;
if (multipartRequest != null) {
List<MultipartFile> files = multipartRequest.getFiles(name);
if (!files.isEmpty()) {
arg = (files.size() == 1 ? files.get(0) : files);
}
}
if (arg == null) {
String[] paramValues = request.getParameterValues(name);
if (paramValues != null) {
arg = (paramValues.length == 1 ? paramValues[0] : paramValues);
}
}
return arg;
}

解决方式:

package pzx.base.config

import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.web.servlet.HandlerInterceptor
import org.springframework.web.servlet.config.annotation.InterceptorRegistry
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter
import java.util.ArrayList
import org.springframework.boot.web.servlet.FilterRegistrationBean
import org.springframework.boot.web.servlet.ServletRegistrationBean
import pzx.web.sys.AuthImageServlet
import javax.servlet.MultipartConfigElement
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.core.MethodParameter
import org.springframework.core.env.Environment
import org.springframework.http.HttpInputMessage
import org.springframework.http.HttpOutputMessage
import org.springframework.http.MediaType
import org.springframework.http.converter.HttpMessageConverter
import org.springframework.web.bind.support.WebDataBinderFactory
import org.springframework.web.context.request.NativeWebRequest
import org.springframework.web.method.support.HandlerMethodArgumentResolver
import org.springframework.web.method.support.HandlerMethodReturnValueHandler
import org.springframework.web.method.support.ModelAndViewContainer
import pzx.base.comm.JsonMap
import pzx.base.extend.FromJson
import pzx.base.extend.ToJson
import java.nio.charset.Charset
import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletRequestWrapper /**
* Created by udi on 2017.3.11.
*/
@Configuration
open class MyWebMvcConfig : WebMvcConfigurerAdapter() { @Bean
open fun filterRegistrationBean(): FilterRegistrationBean {
val registrationBean = FilterRegistrationBean()
val httpBasicFilter = MyAllFilter()
registrationBean.filter = httpBasicFilter
val urlPatterns = ArrayList<String>()
urlPatterns.add("/*")
urlPatterns.add("/**")
registrationBean.urlPatterns = urlPatterns
return registrationBean
} override fun addInterceptors(registry: InterceptorRegistry?) {
if (registry == null) return registry.addInterceptor(MySessionFilter())
.addPathPatterns("/*")
.addPathPatterns("/**")
.excludePathPatterns("/hi")
.excludePathPatterns("/open/**")
.excludePathPatterns("/oh")
.excludePathPatterns("/doc")
.excludePathPatterns("/error")
.excludePathPatterns("/login")
.excludePathPatterns("/registe")
.excludePathPatterns("/swagger-resources/**")
.excludePathPatterns("/v2/**")
} @Bean
fun RegisteAuthImageServlet(): ServletRegistrationBean {
var registration = ServletRegistrationBean(AuthImageServlet())
registration.isEnabled = true
registration.addUrlMappings("/open/getValidateCodeImage")
return registration
} class RequestJsonResolver : HandlerMethodArgumentResolver { //只认是否包含。
override fun supportsParameter(parameter: MethodParameter?): Boolean {
if (parameter!!.parameterName == null) return false;
if (HttpContext.request is MyHttpRequestWrapper) return false;
return (HttpContext.request as MyHttpRequestWrapper).json.containsKey(parameter.parameterName)
} override fun resolveArgument(parameter: MethodParameter?, mavContainer: ModelAndViewContainer?, webRequest: NativeWebRequest?, binderFactory: WebDataBinderFactory?): Any {
var request = webRequest!!.nativeRequest as MyHttpRequestWrapper;
if (parameter!!.parameterName == null) {
throw Error("${request.requestURI} 找不到 ${parameter!!.parameterName}");
}
var map = request.json;//String(request!!.inputStream.readBytes(), Charset.defaultCharset()).FromJson<JsonMap>(); if (map.containsKey(parameter!!.parameterName)) {
return map.get(parameter!!.parameterName)!!;
} return parameter!!.parameterType.newInstance();
} } override fun addArgumentResolvers(argumentResolvers: MutableList<HandlerMethodArgumentResolver>?) {
argumentResolvers?.add(RequestJsonResolver())
super.addArgumentResolvers(argumentResolvers)
}
}

如何接收Map数据:

http://www.codes51.com/article/detail_114729.html
调试发现: SpringMvc可以接收   LinkedHashMap<String, String>  , Map<String,String> , 但不能接收继承 LinkedHashMap 的数据类型。 也不能接收 HashMap 。

估计是这帮SB把代码又写死了。

Model绑定

http://stackoverflow.com/questions/12893566/passing-multiple-variables-in-requestbody-to-a-spring-mvc-controller-using-ajax

https://www.oschina.net/question/227902_162591

<mvc:annotation-driven>
<mvc:argument-resolvers>
<beans:bean class="com.redcollar.bl.commons.extension.JsonArgumentResolver" />
</mvc:argument-resolvers>
</mvc:annotation-driven> 对应的SpringBoot,就是
@Configuration
+
WebMvcConfigurerAdapter

教程:http://starscream.iteye.com/blog/1098880
												

SpringMvc执行过程的更多相关文章

  1. 深入源码分析SpringMVC执行过程

    本文主要讲解 SpringMVC 执行过程,并针对相关源码进行解析. 首先,让我们从 Spring MVC 的四大组件:前端控制器(DispatcherServlet).处理器映射器(HandlerM ...

  2. 浅谈SpringMVC执行过程

    通过深入分析Spring源码,我们知道Spring框架包括大致六大模块, 如Web模块,数据库访问技术模块,面向切面模块,基础设施模块,核心容器模块和模块, 其中,在Spring框架的Web模块中,又 ...

  3. Spring Taco Cloud——Controller的创建(含SpringMVC执行过程&SpringBoot&Spring三者解释及关联)

    在记录这次控制器编写前,对于Spring的感觉就是经常提这样代码好简洁,这样好方便,这个是用来干嘛的诸如之类的话. What is Spring ?这是我想问自己的,一直认为是简化代码利于工程的开源框 ...

  4. 【spring mvc】springmvc在tomcat中的执行过程

    一.WEB容器在启动时,它会为每个WEB应用程序都创建一个对应的ServletContext对象(每个web应用程序唯一),它代表当前web应用web容器提供其一个全局的上下文环境,其为后面的spri ...

  5. 【spring源码学习】springMVC之映射,拦截器解析,请求数据注入解析,DispatcherServlet执行过程

    [一]springMVC之url和bean映射原理和源码解析 映射基本过程 (1)springMVC配置映射,需要在xml配置文件中配置<mvc:annotation-driven >  ...

  6. SpringMVC:自定义视图及其执行过程

    一:自定义视图 1.自定义一个实现View接口的类,添加@Component注解,将其放入SpringIOC容器 package com.zzj.view; import java.io.PrintW ...

  7. springmvc组件组成以及springmvc的执行过程

    springmvc三大组件 处理器映射器:用户请求路径到Controller方法的映射 处理器适配器:根据handler(controlelr类)的开发方式(注解开发/其他开发) 方式的不同区寻找不同 ...

  8. SpringMVC启动过程详解(li)

    通过对SpringMVC启动过程的深入研究,期望掌握Java Web容器启动过程:掌握SpringMVC启动过程:了解SpringMVC的配置文件如何配置,为什么要这样配置:掌握SpringMVC是如 ...

  9. 面试高频SpringMVC执行流程最优解(源码分析)

    文章已托管到GitHub,大家可以去GitHub查看阅读,欢迎老板们前来Star! 搜索关注微信公众号 码出Offer 领取各种学习资料! SpringMVC执行流程 SpringMVC概述 Spri ...

随机推荐

  1. [20171031]markhot.txt

    [20171031]markhot.txt --//昨天看了https://jonathanlewis.wordpress.com/2017/10/02/markhot/,测试看看这样时候可以减少争用 ...

  2. 将 Windows 虚拟机从非托管磁盘转换为托管磁盘

    如果有使用非托管磁盘的现有 Windows 虚拟机 (VM),可通过 Azure 托管磁盘服务将 VM 转换为使用托管磁盘. 此过程会同时转换 OS 磁盘和任何附加的数据磁盘. 本文介绍如何使用 Az ...

  3. CRM JS

    注意事项:Xrm.Page中的方法使用的是实体.字段.关系的逻辑名称.窗体调试:contentIFrame.Xrm.Page.getControl("compositeControlPara ...

  4. MySQL sql_mode=only_full_group_by错误

    今天在测试服务器上突然出现了这么一个MySQL的问题,同样的代码正式服没有问题,那肯定就是出在了配置上,查了一下原因才明白原来是数据库版本为5.7以上的版本, 默认是开启了 only_full_gro ...

  5. Linux 小知识翻译 - 「RAID」

    最近术语「RAID」变得比较有名.「RAID」是指将多个HDD组合起来使用,从而提高存储可靠性的一种技术. 那么,关于 RAID 中的 「RAID 0」「RAID 1」「RAID 5」等各种「RAID ...

  6. SAP CRM 忠诚度相关表的关系图

    这是一张有关会员,积分,活动等内容的相关表的关系图,对相关的开发工作会有帮助. 原文标题:Table schema for managing customer loyality 本文链接:http:/ ...

  7. 使用requests模块保存网络上的图片

    import requests url = 'https://www.baidu.com/img/bd_logo1.png' r = requests.get(url=url) with open(' ...

  8. Robberies HDU - 2955

    直接说题意吧.(什么网友bb了半天题都说不清楚) 给了  P  表示大于这个概率一定被抓住.则P表示被抓住的概率.N表示现在有的银行,pi表示被抓的概率嘛. 然后,就看数学了.肯定不能算被抓的概率啊. ...

  9. Spring配置文件中的那些标签意味着什么(持续更新)

    前言 在看这边博客时,如果遇到有什么不清楚的地方,可以参考我另外一边博文.Spring标签的探索,根据这边文章自己来深入源码一探究竟.这里自己只是简单记录一下各标签作用,每个人困惑不同,自然需求也不一 ...

  10. 在web.xml中通过contextConfigLocation配置spring

    <context-param>         <param-name>contextConfigLocation</param-name>         < ...