1、springMvc介绍
三层架构
-
表现层:负责数据展示
-
业务层:负责业务处理
-
数据层:负责数据操作
MVC(Model View Controller),一种用于设计创建Web应用程序表现层的模式
-
Model(模型):数据模型,用于封装数据
-
View(视图):页面视图,用于展示数据
-
jsp
-
html
Controller(控制器):处理用户交互的调度器,用于根据用户需求处理程序逻辑
-
Servlet
-
SpringMVC
2、入门案例
2.1、案例结构
2.2、pom.xml中导入SpringMVC相关坐标
<dependencies>
<!-- servlet3.1规范的坐标 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<!--jsp坐标-->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.1</version>
<scope>provided</scope>
</dependency>
<!--spring的坐标-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.9.RELEASE</version>
</dependency>
<!--spring web的坐标-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.1.9.RELEASE</version>
</dependency>
<!--springmvc的坐标-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.1.9.RELEASE</version>
</dependency>
</dependencies>
<!--构建-->
<build>
<!--设置插件-->
<plugins>
<!--具体的插件配置-->
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.1</version>
<configuration>
<port>80</port>
<path>/</path>
</configuration>
</plugin>
</plugins>
</build>
2.3、 定义表现层业务处理器Controller,并配置成spring的bean(等同于Servlet)
package com.itheima.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class UserController {
//设定具体Controller的访问路径(等同于Servlet在web.xml中的配置)
//设定当前方法的访问映射地址
@RequestMapping("/save")
//设置当前方法返回值类型为String,用于指定请求完成后跳转的页面
public String save() {
System.out.println("user mvc controller is running...");
return "success.jsp";
//这里的return等于servlet中的 req.getRequestDispatcher("success.jsp").forward(req,resp);
}
}
2.4、spring.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: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/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!--扫描加载所有的控制类类-->
<context:component-scan base-package="com.itheima"/>
</beans>
2.5、web.xml中配置SpringMVC核心控制器,用于将请求转发到对应的具体业务处理器Controller中(等同于Servlet配置)
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<servlet>
<servlet-name>DispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:spring-mvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>DispatcherServlet</servlet-name>
<!--
方式一:带后缀,比如*.action *.do *.aaa
该种方式比较精确、方便,在以前和现在企业中都有很大的使用比例
方式二:/ 不会拦截 .jsp,但是会拦截.html等静态资源(静态资源:除了servlet和jsp之外的js、css、png等)
为什么配置为 / 会拦截静态资源???
因为tomcat容器中有一个web.xml(父),你的项目中也有一个web.xml(子),是一个继承关系
父web.xml中有一个DefaultServlet, url-pattern 是一个 /
此时我们自己的web.xml中也配置了一个 / ,覆写了父web.xml的配置
为什么不拦截.jsp呢?
因为父web.xml中有一个JspServlet,这个servlet拦截.jsp文件,而我们并没有覆写这个配置,所以springmvc此时不拦截jsp,jsp的处理交给了tomcat
如何解决/拦截静态资源这件事?
方式三:/* 拦截所有,包括.jsp
-->
<url-pattern>/</url-pattern> <!--拦截匹配规则的url请求,进入springmvc框架处理-->
</servlet-mapping>
</web-app>
3、入门案例工作流程分析
-
服务器启动
-
加载web.xml中DispatcherServlet
-
读取spring-mvc.xml中的配置,加载所有com.itheima包中所有标记为bean的类
-
读取bean中方法上方标注@RequestMapping的内容
-
-
处理请求
-
DispatcherServlet配置拦截所有请求 /
-
使用请求路径与所有加载的@RequestMapping的内容进行比对
-
执行对应的方法
-
根据方法的返回值在webapp目录中查找对应的页面并展示
-
4、SpringMVC 技术架构图
-
DispatcherServlet:前端控制器, 是整体流程控制的中心,由其调用其它组件处理用户的请求, 有 效的降低了组件间的耦合性
-
HandlerMapping:处理器映射器, 负责根据用户请求找到对应具体的Handler处理器
-
Handler:处理器,业务处理的核心类,通常由开发者编写,描述具体的业务
-
HandlAdapter:处理器适配器,通过它对处理器进行执行
-
View Resolver:视图解析器, 将处理结果生成View视图
-
View:视图,最终产出结果, 常用视图如jsp、 html
5、Spring MVC 九大组件
5.1、HandlerMapping(处理器映射器)
HandlerMapping 是用来查找 Handler 的,也就是处理器,具体的表现形式可以是类,也可以是方法。比如,标注了@RequestMapping的每个方法都可以看成是⼀个Handler。Handler负责具体实际的请求处理,在请求到达后,HandlerMapping 的作用便是找到请求相应的处理器Handler 和Interceptor.
5.2、HandlerAdapter(处理器适配器)
HandlerAdapter 是⼀个适配器。因为 Spring MVC 中 Handler 可以是任意形式的,只要能处理请求即可。但是把请求交给 Servlet 的时候,由于 Servlet 的方法结构都是doService(HttpServletRequest req,HttpServletResponse resp)形式的,要让固定的 Servlet 处理方法调⽤ Handler 来进行处理,便是 HandlerAdapter 的职责。
5.3、HandlerExceptionResolver
HandlerExceptionResolver 用于处理 Handler 产生的异常情况。它的作用是根据异常设置ModelAndView,之后交给渲染方法进行渲染,渲染方法会将 ModelAndView 渲染成页面。
5.4、ViewResolver
ViewResolver即视图解析器,用于将String类型的视图名和Locale解析为View类型的视图,只有一个resolveViewName()方法。从方法的定义可以看出,Controller层返回的String类型视图名viewName 最终会在这里被解析成为View。View是⽤来渲染页面的,也就是说,它会将程序返回的参数和数据填入模板中,生成html文件。ViewResolver 在这个过程主要完成两件事情:ViewResolver 找到渲染所⽤的模板(第⼀件大事)和所用的技术(第⼆件⼤事,其实也就是找到视图的类型,如JSP)并填⼊参数。默认情况下,Spring MVC会自动为我们配置⼀个InternalResourceViewResolver,是针对 JSP 类型视图的。
5.5、RequestToViewNameTranslator
RequestToViewNameTranslator 组件的作用是从请求中获取 ViewName.因为 ViewResolver 根据ViewName 查找 View,但有的 Handler 处理完成之后,没有设置 View,也没有设置ViewName,便要通过这个组件从请求中查找 ViewName。
5.6、LocaleResolver
ViewResolver 组件的 resolveViewName 方法需要两个参数,一个是视图名,一个是 Locale。LocaleResolver 用于从请求中解析出 Locale,比如中国 Locale 是 zh-CN,用来表示一个区域。这个组件也是 i18n 的基础。
5.7、ThemeResolver
ThemeResolver 组件是用来解析主题的。主题是样式、图片及它们所形成的显示效果的集合。Spring MVC 中⼀套主题对应一个 properties文件,里面存放着与当前主题相关的所有资源,如图
片、CSS样式等。创建主题非常简单,只需准备好资源,然后新建⼀个“主题名.properties”并将资源设置进去,放在classpath下,之后便可以在页面中使用了。SpringMVC中与主题相关的类有ThemeResolver、ThemeSource和Theme。ThemeResolver负责从请求中解析出主题名,ThemeSource根据主题名找到具体的主题,其抽象也就是Theme,可以通过Theme来获取主题和具体的资源。
5.8、MultipartResolver
MultipartResolver 用于上传请求,通过将普通的请求包装成 MultipartHttpServletRequest 来实现。MultipartHttpServletRequest 可以通过 getFile() 方法 直接获得文件。如果上传多个文件,还可以调用 getFileMap()方法得到Map<FileName,File>这样的结构,MultipartResolver 的作用就是封装普通的请求,使其拥有文件上传的功能。
5.9、FlashMapManager
FlashMap 用于重定向时的参数传递,比如在处理用户订单时候,为了避免重复提交,可以处理完
post请求之后重定向到一个get请求,这个get请求可以用来显示订单详情之类的信息。这样做虽然
可以规避用户重新提交订单的问题,但是在这个页面上要显示订单的信息,这些数据从哪里来获得
呢?因为重定向时么有传递参数这一功能的,如果不想把参数写进URL(不推荐),那么就可以通
过FlashMap来传递。只需要在重定向之前将要传递的数据写入请求(可以通过ServletRequestAttributes.getRequest()方法获得)的属性UTPUT_FLASH_MAP_ATTRIBUTE中,这样在重定向之后的Handler中Spring就会自动将其设置到Model中,在显示订单信息的页面上就可以直接从Model中获取数据。FlashMapManager 就是用来管理 FalshMap 的。