SpringMVC 的基本概念
三层架构
我们的开发架构一般都是基于两种形式,一种是 C/S 架构,也就是客户端/服务器,另一种是 B/S 架构,也就是浏览器服务器。在 JavaEE 开发中,几乎全都是基于 B/S 架构的开发。那么在 B/S 架构中,系统标准的三层架构包括:表现层、业务层、持久层。
表现层:web层。用来和客户端进行数据交互的。表现层一般会采用MVC的设计模型 (MVC 是表现层的设计模型,和其他层没有关系)
业务层:service 层。它负责业务逻辑处理
持久层: dao 层。负责数据持久化。通俗的讲,持久层就是和数据库交互,对数据库表进行曾删改查的
MVC 模型
MVC 全名是 Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,是一种用于设计创建 Web 应用程序表现层的模式。
Model(模型):数据模型,JavaBean的类。用于数据封装。
View(视图):通常指的就是我们的 jsp 或者 html。作用一般就是展示数据的。
Controller(控制器):是应用程序中处理用户交互的部分。 作用一般就是处理程序逻辑的 。
SpringMVC 概述
是一种基于Java实现的MVC设计模型的请求驱动类型的轻量级WEB框架。 是一个表现层框架。属于 Spring FrameWork 的后续产品,已经融合在 Spring Web Flow 里面。
SpringMVC的入口是一个servlet
SpringMVC入门案例
引入依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
细节:
spring-webmvc中会包含spring-aop,spring-beans,spring-context,spring-core,spring-expression,spring-web
配置核心控制器
在web.xml中配置
<!-- 配置 spring mvc 的核心控制器 -->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--指定SpringMVC配置文件的路径-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
<!--配置servlet对象创建的时间点-->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<!--拦截所有请求-->
<!--<url-pattern>/</url-pattern>-->
<!--拦截.do结尾的请求-->
<url-pattern>*.do</url-pattern>
</servlet-mapping>
细节:
1. <init-param>标签
标签中配置的是SpringMVC配置文件的位置,如果不配置默认去找 /WEB-INF/Servlet名称-servlet.xml。这里的“Servlet名称”指的是核心控制器<servlet-name/>标签中指定的 Servlet 的 name 值。如本示例中会去找/WEB-INF/springmvc-servlet.xml,如果没有则会抛出FileNotFoundException 异常。此处<param-name>的值contextConfigLocation为固定写法,<param-value>的值classpath:springmvc.xml为具体路径,此处指类路径下,即 resources 目录下。
2. <load-on-startup>标签
配置servlet对象创建的时间点,它的值必须是一个整数,表示servlet应该被载入的顺序,当值为0或者大于0时,表示容器在应用启动时就加载并初始化这个servlet。当值小于0或者没有指定时,则表示容器在该servlet被选择时才会去加载。正数的值越小,该servlet的优先级越高,应用启动时就越先加载。当值相同时,容器就会自己选择顺序来加载。
SpringMVC配置文件
springmvc.xml 要和web.xml中配置的保持一致
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
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
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">
<!-- 配置创建 spring 容器要扫描的包 -->
<context:component-scan base-package="com.mg"></context:component-scan>
<!-- 配置视图解析器 -->
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!--前缀-->
<property name="prefix" value="/WEB-INF/pages/"></property>
<!--后缀-->
<property name="suffix" value=".jsp"></property>
</bean>
<!-- 配置spring开启注解mvc的支持。一般开发中,我们都需要写上此标签(虽然从入门案例中看,我们不写也行,随着课程的深入,该标签还有具体的使用场景)-->
<mvc:annotation-driven></mvc:annotation-driven>
</beans>
编写控制器并使用注解配置
@Controller
public class HelloController {
@RequestMapping(path="/hello")
public String sayHello() {
//返回的字符串会和视图解析器配置的前缀、后缀拼接,返回相应页面(/WEB-INF/pages/success.jsp)
return "success";
}
}
jsp页面
此文件要放置在/WEB-INF/pages/路径下,和上面配置视图解析器的前缀prefix值保持一致
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<body>
<h3>入门成功!!</h3>
</body>
</html>
测试
启动Tomcat服务器。访问 http://localhost:8080/index 时会显示index.jsp的内容
入门案例的执行过程及原理分析
案例的执行过程
- 当启动Tomcat服务器的时候,因为配置了load-on-startup标签,所以会创建DispatcherServlet对象,就会加载springmvc.xml配置文件
- 开启了注解扫描,那么HelloController对象就会被创建
- 从index.jsp发送请求,请求会先到达DispatcherServlet核心控制器,根据配置@RequestMapping注解找到执行的具体方法
- 根据执行方法的返回值,再根据配置的视图解析器,去指定的目录下查找指定名称的JSP文件
- Tomcat服务器渲染页面,做出响应
SpringMVC 的请求响应流程
请求响应流程简单分析
- 浏览器提交请求到中央调度器
- 中央调度器直接将请求转给处理器映射器。
- 处理器映射器会根据请求,找到处理该请求的处理器,并将其封装为处理器执行链后返回给中央调度器。
- 中央调度器根据处理器执行链中的处理器,找到能够执行该处理器的处理器适配器。
- 处理器适配器调用执行处理器。
- 处理器将处理结果及要跳转的视图封装到一个对象 ModelAndView 中,并将其返回给处理器适配器。
- 处理器适配器直接将结果返回给中央调度器。
- 中央调度器调用视图解析器,将 ModelAndView 中的视图名称封装为视图对象。
- 视图解析器将封装了的视图对象返回给中央调度器
- 中央调度器调用视图对象,让其自己进行渲染,即进行数据填充,形成响应对象。
- 中央调度器响应浏览器。
入门案例中涉及的组件
DispatcherServlet:前端控制器 (中央调度器)
用户请求到达前端控制器,它就相当于 mvc 模式中的 c, dispatcherServlet 是整个流程控制的中心,由它调用其它组件处理用户的请求, dispatcherServlet 的存在降低了组件之间的耦合性。
HandlerMapping:处理器映射器
HandlerMapping 负责根据用户请求找到 Handler 即处理器, SpringMVC 提供了不同的映射器实现不同的映射方式,例如:配置文件方式,实现接口方式,注解方式等
Handler:处理器
它就是我们开发中要编写的具体业务控制器。由 DispatcherServlet 把用户请求转发到 Handler。由Handler 对具体的用户请求进行处理。
HandlAdapter:处理器适配器
通过 HandlerAdapter 对处理器进行执行,这是适配器模式的应用,通过扩展适配器可以对更多类型的处理器进行执行。
View Resolver:视图解析器
View Resolver 负责将处理结果生成 View 视图, View Resolver 首先根据逻辑视图名解析成物理视图名。即具体的页面地址,再生成 View 视图对象,最后对 View 进行渲染将处理结果通过页面展示给用户。