Spring MVC优势:
- 拥有强大的灵活性、非侵入性和可配置性
- 提供了一个前端控制器DispatcherServlet,开发者无需额外开发控制器对象
- 分工明确,包括控制器、验证器、命令对象、模型对象、处理程序映射视图解析器等等,每一个功能实现由一个专门的对象负责完成
- 可以自动绑定用户输入,并正确的转换数据类型。例如SpringMVC能自动解析字符串,并将其设置为模型的int或者float类型的属性
- 使用一个key/value的map对象实现更加灵活的模型数据传输
- SpringMVC内置了常见的校验器,可以校验用户输入,如果校验不通过,则重定向回输入表单。输入校验是可选的,并且支持编程方式以及声明方式
- 支持国际化
- 支持多种视图技术,最常见的是JSP和Velocity和FreeMaker
- Spring提供了一个简单而强大的JSP标签库,支持数据绑定功能,使得编写JSP页面更加容易
一个小回顾
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--配置controller,映射/hello.do请求-->
<bean name="/hello.do" class="com.cskaoyan.controller.FirstController"/>
<!--根据Bean的名字去做url映射的 映射器-->
<!--处理映射器将Bean的name作为url进行查找,需要在截止controller时指定name(url)-->
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
<!--处理器适配器,专门去适配一个特定的controller,所有处理适配器都要实现HandlerAdapter接口-->
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
<!--视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"/>
</beans>
TIP
SpringMVC 建议把所有的视图页面存放在WEB-INF文件夹下,这样可以保护视图页面,避免直接向视图页面(jsp等)发送请求,而是由实现了Controller接口的自定义控制器来呈现。
使用MVC框架就应该严格遵守MVC思想。MVC框架不赞成浏览器直接访问Web应用的视图页面,用户的所有请求都应该只向Controller发送,由Controller调用(Dao&Bean)/view向用户呈现数据
- 注解配置MVC
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!--spring可以自动去扫描base-pack下面的包或者子包下面的Java文件,如果扫描到有
Spring的相关注解的类,则把这些类注册为Spring的bean-->
<context:component-scan base-package="com.bamzhy"/>
<!--配置Annotation类型的处理映射器,根据请求查找映射-->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>
<!--配置Annotation类型的处理器适配器,完成@RequestMapping标注方法的调用-->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/>
<!--视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"/>
</beans>
- 这个是最方便方法
<context:component-scan base-package="com.bamzhy"/>
<!--注解驱动:替我们自动配置最新版的注解的处理器映射器和处理器适配器-->
<mvc:annotation-driven></mvc:annotation-driven>
SpringMVC执行的流程
Spring MVC的开发步骤
- 在web.xml中定义前端控制器DispatcherServlet来拦截用户请求,由于web应用时基于请求/响应架构的应用,所以不管哪个MVC web框架都需要在Web.xml中配置该框架的核心servlet或者filter,这样才可以让该框架介入web应用中。
- 如果需要以post方式提交请求,则定义包含表单数据的JSP页面。如果仅仅是以get方式发送请求,则无需经过这一步。
- 定义处理用户请求的Handler类,可以实现Controller接口或者使用@ controller注解。
Tip
Controller并未接收到用户请求,它怎么能够处理用户的请求呢?MVC框架的底层机制是:前端Servlet接收到用户请求后,通常会对用户请求进行简单的预处理,例如解析、封装参数等等,然后通过反射来创建controller实例,并调用Controller的指定方法(**实现Controller接口的handleRequest方法,而基于注解的控制器可以是任意方法**)
当Servlet拦截用户请求以后,它如何知道创建哪个Controller接口的实例呢?
- 利用xml文件:例如在xml文件中描述haha请求对应使用FirstController类。
利用注解:例如使用@ Controller描述一个类,并且使用注解 @ requestMapping(value=”/haha”)描述haha请求对应的方法。
在Spring MVC 框架中,控制器实际上由两个部分共同组成,即拦截所有用户请求和处理请求的通用代码都有前端控制器DispatcherServlet完成,而实际的业务控制(例如调用后台业务逻辑代码,返回处理结果等)都由Controller处理
Java领域的绝大部分MVC框架都很喜欢使用xml问价你来进行配置管理,即配置哪个请求对应哪个Controller进行处理,从而让前端控制器根据该配置来创建合适的Controller实例,并且调用该Controller的业务控制方法。
< bean name=”/haha” class=”com.bamzhy.controller.MyFirstServlet” >
现在大多使用配置来实现。
现在几乎所有MVC矿建都使用约定优于配置的思想,也就是采用约定方式来规定用户请求地址和Handle之间的对应关系(用注解)。当Controller处理用户请求结束后,通常会返回一个ModelAndView对象,该对象中应该包含返回的view名或者view名和model,这个view名就代表需要显示的物理视图资源。如果controller需要把一些数据传给视图资源,则可以通过模型对象。
Spring MVC的完整请求流程
1、用户向服务器发送请求,请求被DispatcherServlet截获
2、DispatcherServlet对请求的URL(统一资源定位符)进行解析,得到URI(请求资源标识符)。根据URI调用HandlerMapping获得该Handler配置的所有相关的对象,包括Handler对象以及Handler对象对应的拦截器,这些对象会被封装到一个HandlerExecutionChain对象中返回
3、DispatcherServlet根据获得Handler选择一个合适的HandlerAdaper。HandlerAdaper的设计符合面向对象中的单一职责原则,代码架构清晰,便于维护,最重要的是diamante可复用性高。HandlerAdaper会被用于处理多种Handler,调用Handler实际处理请求的方法.
4、提取请求中的模型数据,开始执行Handler,在填充Handler的入参过程中,根据配置,Spring将帮你做一些额外的工作。
消息转换 :将请求消息如Json、xml数据转换成一个对象,将对象转换为指定的响应信息。
数据转换:对请求消息进行数据转换,比如String转换成Integer、Double等
数据格式化:对请求消息进行数据格式化,如将字符串转换成格式化数字或者格式化日期等
数据验证:验证数据的有效性(长度格式等)验证结果存储到BindingResult或Error中
5、Handler执行完成后,向DispatcherServlet返回一个ModelAndView对象,ModelAndVIew对象汇总应该包含视图名或者视图+模型
6、根据返回的ModelAndView对象,选择一个合适的ViewResolver(视图解析器)返回给DispatcherServlet
7、ViewResolver结合Model和view来渲染视图
8、将视图渲染结果返回给客户端