SpringMVC的请求处理步骤
1、浏览器发送请求到前段控制器DispatcherServlet。
2、DispatcherServlet请求处理器映射器HandlerMapping查找Handler。根据xml配置以及注解配置进行查找。
3、HandlerMapping向前端控制器DispatcherServlet返回Handler。
4、DIspatcherServlet请求处理器适配器HandlerAdapter处理Handler。
5、HandlerAdapter处理Handler。
6、Handler执行完毕返回给HandlerAdapter模型和视图(ModelAndView)。
7、HandlerAdapter向DispatcherServlet返回ModelAndView。ModelAndView是springmvc的一个底层对象,包括model和view。
8、DispatcherServlet请求视图解析器ViewResolver进行视图解析。根据逻辑视图名解析为真正的视图。
9、视图解析器向前端控制器DispatcherServlet返回View
10、前段控制器进行视图渲染。视图渲染将模型数据填充到Request域。
11、DispatcherServlet向浏览器响应结果。
组件:
1、前端控制器DispatcherServlet
接收请求,响应结果,相当于转发器
2、处理器映射器HandlerMapping
根据请求的url来查找Handler
3、Handler需要程序员开发
执行业务逻辑,需要按照HandlerAdapter的要求去开发
4、处理器适配器HandlerAdapter
按照特定规则执行Handler。在开发Handler的时候要按照HandlerAdapter的要求去开发。
5、视图解析器ViewResolver(不需要程序员开发)
进行视图解析,根据逻辑视图名解析成真正的视图
6、视图View(需要程序员开发jsp)
View是一个接口,实现类支持不同类型的View(jsp,freeMark、pdf)
非注解的处理器映射器和适配器
1、映射器
<!--BeanName映射器-->
<bean id="handlerMapping" class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
<!--简单url映射器-->
<bean id="urlHandlerMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings" >
<props>
<!--对Controller进行url映射,同一个控制器Bean可以配置多个url-->
<prop key="/queryItems1.action">/queryItems.action</prop>
<prop key="/queryItems2.action">/queryItems.action</prop>
</props>
</property>
</bean>
当有多个处理器映射器并存的时候,前端控制器会判断url能让哪些映射器映射,就让正确的映射器处理。
2、非注解的适配器
org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter
<bean id="httpRequestHandlerAdapter" class="org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter"/>
该映射器适配器要求能处理的Handler必须实现org.springframework.web.HttpRequestHandler接口
@Override
public boolean supports(Object handler) {
return (handler instanceof HttpRequestHandler);
}
注解的处理器映射器和适配器
1、映射器
在Spring 3.1 之前用的注解的处理器映射器为org.springframework.servlet.mvc.annnotation.DefaultAnnotationHandlerMapping
在Spring 3.1 之后用的注解的处理器映射器为org.springframework.servlet.mvc.method.annnotation.RequestMappingHandlerMapping
2、适配器
在Spring 3.1 之前用的注解的适配器为 org.springframework.web.servlet.mvc.annotation.AnnotationMethodhandlerAdapter
在Spring 3.1 之后用的注解的适配器为 org.springframework.web.servlet.mvc.method.annotation.RequestMappinghandlerAdapter
配置注解的映射器和适配器
<!--注解适配器 -->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/>
<!--注解映射器 -->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>
<!-- 使用mvc的注解驱动标签可以代替注解驱动的映射器和适配器 -->
<mvc:annotation-driven/>
注意:注解的处理器映射器和适配器必须配对使用
SpringMvc的参数绑定
1、从客户请求KV数据,经过参数绑定,将KV数据绑定在controller中。接收页面提交的数据是通过方法形参来接收,而不是controller定义成员变量来接收。
处理器适配器将调用参数绑定组件,将前端传过来的KV数据转换为controller方法的形参。在Spring早期版本中使用PropertyEditor(只能将字符串转成java对象),后期使用Convertor(进行任意类型的转换),
Spring提供了很多Convertor的实现。但是,对于日期格式的字符串,需要自定义。
2、参数绑定默认支持的类型
直接在controller方法的形参上定义下边类型的对象,就可以直接使用这些对象。在参数绑定的过程中,如果遇到下边的类型,就可以直接进行绑定
HttpServletRequest
HttpPServletResponse
HttpSession 通过session对象获取存放在session中的镀锡查能
Model/ModelMap model是一个接口,modelMap是一个实现
对于简单类型,可以在controller方法的形参中直接定义。如果不使用@RequestParam,则要求形参名和前端传入的参数名必须一致。
使用@Required修饰controller方法的形参,则该参数必须传递。
使用@DefaultValue 可以指定controller方法形参的默认值
3、自定义controller参数转化器
<mvc:annotation-driven conversion-service="conversionService"/>
<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name="converters">
<list>
<bean class="com.andy.handler.convertor.CustomDataConvertor"/>
</list>
</property>
</bean>
4、SpringMvc和struts之间的区别
SpringMvc是基于方法开发,不能将controller方法的形参在方法体中传给方法所在的类的成员变量。
原因是因为SpringMvc在创建Handler的时候只包含一个方法,方法里的参数在方法返回的时候就被销毁了。
基于此,
SpringMvc可以进行单例开发,并且提倡进行单例开发
SpringMvc的开发模式,更符合Service的开发模式
struts通过类的成员变量接收参数,所以无法进行单例开发,只能进行多例开发。
测试表明struts慢的原因在于struts的标签。