用户协议通过http协议到达前端控制器,前端控制器判断该有谁来处理,将请求带给controller(控制器),控制器了解业务处理逻辑细节(负责数据抽取),将业务逻辑生成数据返回给前端控制器,前端控制器再将业务逻辑分发给业务视图,由业务视图呈献业务页面,再将业务页面返还给前端控制器,最终返还给客户端。
MVC本质:MVC的核心思想是业务数据的抽取同业务数据呈现相分离。
SpringMVC框架介绍
Spring 框架提供了构建 Web 应用程序的全功能 MVC 模块。使用 Spring 可插入的 MVC 架构,可以选择是使用内置的 Spring Web 框架还是 Struts 这样的 Web 框架。通过策略接口,Spring 框架是高度可配置的,而且包含多种视图技术,例如 JavaServer Pages(JSP)技术、Velocity、Tiles、iText 和 POI。Spring MVC 框架并不知道使用的视图,所以不会强迫您只使用 JSP 技术。
Spring MVC 分离了控制器、模型对象、分派器以及处理程序对象的角色,这种分离让它们更容易进行定制
Spring的MVC框架主要由DispatcherServlet、处理器映射、处理器(控制器)、视图解析器、视图组成。
SpringMVC就是通过DispatcherServlet将一堆组件串联起来的Web框架。
SpringMVC的原理
SpringMVC接口解释
DispatcherServlet接口:
Spring提供的前端控制器,所有的请求都有经过它来统一分发。在DispatcherServlet将请求分发给Spring Controller之前,需要借助于Spring提供的HandlerMapping定位到具体的Controller。
HandlerAdapter接口:
HandlerAdapter相当于controller,DispatcherServelet调用各种HandlerAdapter来实现任务分发给相关的业务逻辑。
HandlerInterceptor:
HandlerInterceptor是一个接口,可以用来在Handler调用之前、之后,以及view呈现后可以做很多事情。
HandlerMapping接口:
HandlerMapping是负责确定DispatcherServelet与controller之间映射的类,告诉DispatcherServelet,在请求到来后,由哪个controller来响应这个请求。
Controller接口:
Controller将处理用户请求,这和Struts Action扮演的角色是一致的。一旦Controller处理完用户请求,则返回ModelAndView对象给DispatcherServlet前端控制器,ModelAndView中包含了模型(Model)和视图(View)。
ViewResolver接口:
Spring提供的视图解析器(ViewResolver)在Web应用中查找View对象,从而将相应结果渲染给客户。
SpringMVC运行原理
-
客户端请求提交到DispatcherServlet
-
由DispatcherServlet控制器查询一个或多个HandlerMapping,找到处理请求的Controller
-
DispatcherServlet将请求提交到Controller
-
Controller调用业务逻辑处理后,返回ModelAndView
-
DispatcherServlet查询一个或多个ViewResoler视图解析器,找到ModelAndView指定的视图
-
视图负责将结果显示到客户端
DispatcherServlet是整个Spring MVC的核心。它负责接收HTTP请求组织协调Spring MVC的各个组成部分。其主要工作有以下三项:
- 截获符合特定格式的URL请求。
- 初始化DispatcherServlet上下文对应的WebApplicationContext,并将其与业务层、持久化层的WebApplicationContext建立关联。
- 初始化Spring MVC的各个组成组件,并装配到DispatcherServlet中。
配置SpringMVC需要的配置文件
DispatcherServlet是整个Spring MVC的核心,SpringMVC所有的请求都会通过这个前端控制器。
我们可以根据需要配置一个或多个ApplicationContext,常见的做法是配置一个根ApplicationContext和一个前端ApplicationContext。前端ApplicationContext定义网络相关的配置,根ApplicationContext配置数据库等网络无关的组件。这样的话就需要web.xml写成类似这样的。
它配置的地方是在web.xml里面:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<!-- 配置全局的applicationContext -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>
<!-- 配置spring的核心servlet -->
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<!--如果只需要一个ApplicationContext,值留空-->
<param-value>classpath:spring/dispatcher-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!-- 该监听器将在web容器启动时激活spring -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 处理有JavaBean、Introspector的使用而引起的缓冲泄露,建议配置此监听器 -->
<listener>
<listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>
</listener>
<!-- 编码过滤器 -->
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- session的有效时间 -->
<session-config>
<session-timeout>60</session-timeout>
</session-config>
</web-app>
配置的时候还指明了contextConfigLocation,这样就会去加载这个applicationContext.xml了。
在上面的配置中,我们创建了两个ApplicationContext,一个是全局的,另一个是前端控制器dispatcher-servlet使用的。
这里的ApplicationContext其实是一个WebApplicationContext,它可以配置一些网络相关的组件,例如视图解析器、异常解析器、主题解析器等等。
由于SpringMVC启动的时候会读取WEB-INF/applicationContext.xml
所以要在WEB-INF下创建一个空的applicationContext。xml
配置视图解析器
spatcherServlet控制器查询一个或多个HandlerMapping,找到处理请求的Controller。这里其实是通过在dispatcher-servlet.xml配置了扫描路径以及开启了注解驱动来实现的。
dispatcher-servlet.xml中的配置:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
<!-- 指定让Spring的DispatcherServlet作为默认Servlet,这样我们就可以让Spring处理根路径/的请求了。
如果不加这个,那么根路径的请求默认会由服务器来处理。 -->
<mvc:default-servlet-handler/>
<!-- 启用MVC的注解支持。如果不添加这个,那么我们就需要在XML文件中为每个控制器写一个Bean配置 -->
<mvc:annotation-driven/>
<!-- 用来扫描指定的路径下的包,告诉Spring从哪里搜索注解来加载组件用的 -->
<context:component-scan base-package="com.meng"/>
</beans>
context:component-scan说明了要扫描com.meng.demo这个包下所有的类。
这里要注意一下,在开发中有用到注解的类一定都要在这个demo包下,不然就会抛异常的。
加载了扫描路径后,还要开启注解驱动,这样才能认到代码中使用到的注解,,比如@Controller这个注解。
<mvc:annotation-driven />
ViewResoler视图解析器对应配置里面的
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 前缀 -->
<property name="prefix" value="/WEB-INF/pages/"/>
<!-- 后缀 -->
<property name="suffix" value=".jsp"/>
</bean>
这样,当controller中方法返回的是
return "index";
的时候,实际是指向了/WEB-INF/pages/index.jsp这个页面。
上面的配置可以使用mvc命名空间简化。我们可以使用如下的配置替代上面的视图解析器配置。
<mvc:view-resolvers>
<mvc:jsp view-class="org.springframework.web.servlet.view.JstlView"
prefix="/WEB-INF/jsp/"
suffix=".jsp"/>
</mvc:view-resolvers>
创建Controller
package com.meng;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("/mvc")
public class MainController {
@RequestMapping(value = "/index")
public String index(Model model) {
model.addAttribute("name", "李帆");
return "index";
}
}
启动服务器访问 http://localhost:8080/mvc/index
网友评论