SpringMVC思维导图(知识点总结,含面试题整理)
2021-04-12 08:30:18 13 举报
AI智能生成
SpringMVC工作原理、程序运行流程图深入理解、Spring与SpringMVC的整合 知识点设计REST风格、视图解析、相关标签、处理JSON、拦截器 公众号【小张日拱一卒】,回复ssm获取视频文档资源。
作者其他创作
大纲/内容
SpringMVC概述
SpringMVC是什么
实现MVC设计模式
模型-视图-控制器分离
web层解耦
MVC
model模型层
项目中实体Javabean
装载并传输数据
view视图层
项目中jsp展示数据
control Servlet控制层
处理请求
通过MVC注解
POJO(Plain Ordinary Java Object)成为处理请求的控制器
普通原始Java对象不需要继承任何接口和类
Servlet要继承HttpServlet
@Controller注解
通过组件扫描
加注解的类在配置文件自动生成bean标签
以类首字母小写为id
或@Controller(value=“aaa”)
id为“aaa”
才会作为控制层进行处理
操作
springMVC-servlet.xml
<context:component-scan base-package="org.xinzhang.springmvctest"/>
处理请求与响应
封装Servlet
支持REST风格URL请求
Restful写法
SpringMVC 工作原理了解吗?(面试概括型)
客户端(浏览器)发送请求
到前端控制器DispatcherServlet
web.xml中配置
<servlet>
<servlet-name>springServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springMVC.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<servlet-name>springServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springMVC.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
springServlet为自定义名称
contextConfigLocation
DispatcherServlet 中的属性名
设置SpringMVC配置文件的位置和名称
classpath
当classpath不加*的时候表示引用当前项目类路径下满足条件的文件
可以对应src/main/resources文件夹下
当classpath加*的时候表示引用当前项目或者所引用jar包里面满足条件的文件
在maven项目中经常引入jar包,把配置文件放在jar包里
springMVC.xml
存放到src/main/resources文件夹下
load-on-startup
元素标记容器,是否在web应用程序启动时加载此servlet
实例化并调用其init()方法
值是整数,表示servlet被加载的先后顺序
值越小,servlet的优先级越高,就越先被加载
/* 与 / 的区别
<url-pattern>/</url-pattern>
匹配如/login的路径型url
不会匹配到模式为*.jsp的后缀型url
/ 自动过滤jsp的访问
跳转不需要对所有请求进行处理
< url-pattern>/*</url-pattern>
匹配所有url
包括/login,*.jsp,*.js和*.html等
/* 对所有请求进行处理
DispatcherServlet调用HandlerMapping
解析请求得到Handler
springMVC-servlet.xml
配置文件组件扫描
<context:component-scan base-package="org.xinzhang.springmvctest"/>
Handler(contrller控制器)
交给HandlerAdapter(适配器)处理
普通java文件扫描@controller注解
@Controller
public class TestController{}
public class TestController{}
HandlerAdapter处理Handler请求
处理相关业务逻辑
请求定位方法
@RequestMapping(value = "hello",method = RequestMethod.GET)
public String hello(String username,String password){}
public String hello(String username,String password){}
返回ModelAndView对象
Model返回数据对象
View:逻辑上的view
return "success";
视图解析ViewResolver
逻辑view查找实际view
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/view/"/>
<property name="suffix" value=".jsp"/></bean>
<property name="prefix" value="/WEB-INF/view/"/>
<property name="suffix" value=".jsp"/></bean>
DispatcherServlet做视图渲染(把model模型数据填充到view视图中)
DispatcherServlet响应客户端(浏览器)
程序运行流程图(理解深入型)
用户向服务器发送请求,请求被SpringMVC 前端控制器 DispatcherServlet捕获,进行比较分析过滤
servlet标签 的servlet name:spring DispatcherServlet url匹配 (servlet mapping标签 )
DispatcherServlet对请求URL进行解析,得到请求资源标识符(URI):判断请求URI对应的映射
不存在
再判断是否配置了mvc:default-servlet-handler
如果没配置,则控制台报映射查找不到,客户端展示404错误
如果有配置,则执行目标资源(一般为静态资源,如:JS,CSS,HTML)
存在
执行下面流程
根据该URI,调用HandlerMapping(所有的请求和处理器之间的关系)获得该Handler配置的所有相关的对象(包括Handler对象以及Handler对象对应的拦截器),最后以HandlerExecutionChain(找到某一个请求和处理的关系和拦截器)对象的形式返回
DispatcherServlet 根据获得的Handler,选择一个合适的HandlerAdapter
HandlerAdapter:处理器适配器,执行handler/执行处理请求的方法
handler :处理器,控制层中的方法
如果成功获得HandlerAdapter后,此时将开始执行拦截器的preHandler(...)方法【正向】
提取Request中的模型数据,填充Handler入参,开始执行Handler(Controller)方法,处理请求。在填充Handler的入参过程中,根据你的配置,Spring将帮你做一些额外的工作
HttpMessageConveter
①将请求消息(如Json、xml等数据)转换成一个对象,将对象转换为指定的响应信息
②数据转换:对请求消息进行数据转换。如String转换成Integer、Double等
③数据格式化:对请求消息进行数据格式化。 如将字符串转换成格式化数字或格式化日期等
④数据验证: 验证数据的有效性(长度、格式等),验证结果存储到BindingResult或Error中
Handler执行完成后,向DispatcherServlet 返回一个ModelAndView对象
此时将开始执行拦截器的postHandle(...)方法【逆向】
根据返回的ModelAndView(此时会判断是否存在异常:如果存在异常,则执行HandlerExceptionResolver进行异常处理)
选择一个适合的ViewResolver(必须是已经注册到Spring容器中的ViewResolver)返回给DispatcherServlet,根据Model和View,来渲染视图
选择一个适合的ViewResolver(必须是已经注册到Spring容器中的ViewResolver)返回给DispatcherServlet,根据Model和View,来渲染视图
在返回给客户端时需要执行拦截器的AfterCompletion方法【逆向】
将渲染结果返回给客户端
@RequestMapping注解
为请求和控制层中方法建立映射关系
value
请求路径
支持Ant路径风格
?
匹配文件名中一个字符
*
匹配文件名中任意字符
**
匹配多层路径
method
请求方式
客户端发送请求和method值一致,才能处理请求
不匹配:405
GET 查询 POST 添加 PUT 修改 DELETE 删除
可加在类上,同时加在方法上
@RequestMapping(value="/testPathVariable/{id}",method=RequestMethod.GET)
public String testPathVariable(@PathVariable("id") Integer id){
System.out.println("testPathVariable...id="+id);
return "success";}
public String testPathVariable(@PathVariable("id") Integer id){
System.out.println("testPathVariable...id="+id);
return "success";}
@PathVariable
带占位符的URL(Spring3.0 新增)
将 URL 中占位符参数绑定到控制器处理方法的入参中
浏览器的请求
<a href="springmvc/testPathVariable/1001">testPathVariable GET</a>
该功能在 SpringMVC 向 REST 目标挺进发展过程中具有里程碑的意义
@RequestMapping(value = "param")
public String testRequestParam(@RequestParam(value = "username") String username,
@RequestParam(value = "age",required = false,defaultValue = "1") int age){
System.out.println("testRequestParam username ="+username+",age ="+age);
return "success";
}
public String testRequestParam(@RequestParam(value = "username") String username,
@RequestParam(value = "age",required = false,defaultValue = "1") int age){
System.out.println("testRequestParam username ="+username+",age ="+age);
return "success";
}
@RequestParam
注解用于映射请求参数
value
映射请求参数名称
required
设置请求参数是否必须
设置必须,但请求未指定参数
报400错误:客户端请求语法错误,服务器无法理解
require为false,defaultValue
设置默认值,当没有传递参数时使用该值
浏览器的请求
<a href="param?username=xinzhang&age=23">测试@RequestParam</a>
REST(Representational State Transfer)表述性状态传递
面向资源
解决URL统一资源定位符混乱问题
REST利用了HTTP本身特征,如HTTP动词、HTTP状态码、HTTP报头等等
https://localhost:8080/myweb/getDogs --> GET /rest/api/dogs 获取所有小狗狗
https://localhost:8080/myweb/addDogs --> POST /rest/api/dogs 添加一个小狗狗
https://localhost:8080/myweb/updateDogs/:dog_id --> PUT /rest/api/dogs/:dog_id 修改一个小狗狗
https://localhost:8080/myweb/deleteDogs/:dog_id --> DELETE /rest/api/dogs/:dog_id 删除一个小狗狗
https://localhost:8080/myweb/addDogs --> POST /rest/api/dogs 添加一个小狗狗
https://localhost:8080/myweb/updateDogs/:dog_id --> PUT /rest/api/dogs/:dog_id 修改一个小狗狗
https://localhost:8080/myweb/deleteDogs/:dog_id --> DELETE /rest/api/dogs/:dog_id 删除一个小狗狗
返回结果格式固定
第一行永远是操作失败或者成功的状态码
第二行是返回的类型
第三行内容的长度
第五行开始是内容
REST 系统特征
客户-服务器(Client-Server)
提供服务的服务器和使用服务的客户需要被隔离对待
无状态(Stateless)
可缓存(Cachable)
服务器必须让客户知道请求是否可以被缓存
分层系统(Layered System)
服务器和客户之间通信必须被标准化:允许服务器和客户之间的中间层(代理,网关等)可以代替服务器对客户的请求进行回应
统一接口(Uniform Interface)
客户和服务器之间通信的方法必须是统一化的
RESTful架构风格规定,数据的元操作,即CRUD(create, read, update和delete,即数据的增删查改)操作
分别对应于HTTP方法:GET用来获取资源,POST用来新建资源(也可以用于更新资源),PUT用来更新资源,DELETE用来删除资源
PUT/DELETE需要HiddenHttpMethodFilter过滤器
统一数据操作接口,仅通过HTTP方法,完成对数据的所有增删查改工作
视图解析
视图作用
处理模型数据
实现页面跳转
转发、重定向
处理后呈现给客户
view类型
InternalResourceView
转发视图
默认使用的视图实现类
Jstlview
转发视图
JSP文件使用了JSTL国际化标签功能,使用该视图类
RedirectView
重定向视图
视图对象由视图解析器实例化
视图:无状态的,线程安全
mvc:view-controller标签
<mvc:view-controller path="/success" view-name="success"/>
直接响应SpringMVC渲染的页面
无需经过控制器来执行结果
请求路径
http://localhost:8080/项目名/success
转发重定向
控制器方法返回字符串中带有
前缀 forward:
forward:success.jsp:会完成一个到 success.jsp 的转发操作
前缀 redirect:
redirect:success.jsp:会完成一个到 success.jsp 的重定向的操作
相关标签
<mvc:default-servlet-handler />
追根溯源
早期SpringMVC不能处理好静态资源,在web.xml中配置DispatcherServlet请求映射,使用*.do、*.xhtml
请求带后缀的url,无法采用真正的REST风格URL
DispatcherServlet请求映射配置为"/",Spring MVC将捕获Web容器所有的请求
包括静态资源的请求,SpringMVC当成普通请求,找不到对应处理器而导致错误
解决方案
方式一:<mvc:default-servlet-handler />
会在Spring MVC上下文中定义org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler
它会对进入DispatcherServlet的URL进行筛查
如果发现是静态资源请求,将该请求转由Web应用服务器默认的Servlet处理
如果不是静态资源的请求,才由DispatcherServlet继续处理
方式二:<mvc:resources />
更进一步,由Spring MVC框架自己处理静态资源,并添加一些有用的附加值功能
允许静态资源放在任何地方,如WEB-INF目录下、类路径下等
通过location属性指定静态资源的位置
可以使用诸如"classpath:"等的资源前缀指定资源位置。传统Web容器的静态资源只能放在Web容器的根路径下,<mvc:resources />完全打破了这个限制
依据Page Speed、YSlow等浏览器优化原则对静态资源提供优化
通过cacheSeconds属性指定静态资源在浏览器端的缓存时间,一般可将该时间设置为一年,以充分利用浏览器端的缓存
在输出静态资源时,会根据配置设置好响应报文头的Expires 和 Cache-Control值
在接收到静态资源的获取请求时,会检查请求头的Last-Modified值,如果静态资源没有发生变化,则直接返回303相应状态码,提示客户端使用浏览器缓存的数据,而非将静态资源的内容输出到客户端,以充分节省带宽,提高程序性能
<mvc:resources location="/,classpath:/META-INF/publicResources/" mapping="/resources/**"/>
将Web根路径"/"及类路径下 /META-INF/publicResources/ 的目录映射为/resources路径
假设Web根路径下拥有images、js这两个资源目录,在images下面有bg.gif图片,在js下面有test.js文件
通过 /resources/images/bg.gif 和 /resources/js/test.js 访问这两个静态资源
<context:annotation-config/>
仅能在已经注册过的bean上起作用,对于没有在spring容器中注册的bean,并不能执行任何操作
< context:component-scan base-package="XX.XX"/>
除了具有前面功能外,可自动将带有@component,@service,@Repository等注解的对象注册到spring容器中
< context:annotation-config />和 < context:component-scan>同时存在,前者会被忽略。如@autowire,@resource等注入注解只会被注入一次
< mvc:annotation-driven/>
提供Controller请求转发,json自动转换等功能
写一个最简单的返回ModelAndView的Controller,不加annotation-driven可以运行,但如果改成返回Json对象加上ResponseBody就会报错
基础bean只能提供最基础服务,扩展功能如JSON、XML、Valid等,根据classpath有没有相关依赖来决定要不要添加对应的bean或者属性
处理JSON
JS里的一种类型 数据交互格式
JSON两种格式
JSON对象{key:value ,key:value,…}
JSON对象解析方式
对象.key
JSON数组[value1 ,value2 …]
JSON数组的解析方式
for循环遍历
java对象转换json
Bean和map转换JSON对象
List转换Json 数组
springMVC处理json的四个条件
Maven依赖
jackson-annotations、jackson-core、jackson-databind
在springMVC的配置文件中开启MVC驱动
<mvc:annotation-driven />
在处理ajax请求的方法上加上注解@ResponseBody
@ResponseBody 加入之后不能实现页面跳转 ,实现数据响应客户端 就算返回的是字符串(逻辑视图)也会当成响应数据
将要转换为json且响应到客户端的数据,直接作为该方法的返回值返回
HttpMessageConverter<T>
Spring3.0 新增接口,负责将请求信息转换为对象(类型为 T),将对象(类型为 T)输出为响应信息
使用 HttpMessageConverter<T> 将请求信息转化并绑定到处理方法的入参中,或将响应结果转为对应类型的响应信息,Spring 提供了两种途径
使用 @RequestBody / @ResponseBody 对处理方法进行标注
首先根据请求头或响应头的 Accept 属性选择匹配的 HttpMessageConverter
进而根据参数类型或泛型类型的过滤得到匹配的 HttpMessageConverter, 若找不到可用的 HttpMessageConverter 将报错
进而根据参数类型或泛型类型的过滤得到匹配的 HttpMessageConverter, 若找不到可用的 HttpMessageConverter 将报错
使用 HttpEntity<T> / ResponseEntity<T> 作为处理方法的入参或返回值
拦截器
Filter
对请求进行过滤,过滤成功不被拦截,才会被DispatcherServlet进行处理
Spring MVC也可以使用拦截器对请求进行拦截处理,用户可以自定义拦截器来实现特定的功能
自定义的拦截器可以实现HandlerInterceptor接口
也可以继承HandlerInterceptorAdapter 适配器类
preHandle()
这个方法在业务处理器处理请求之前被调用,在该方法中对用户请求 request 进行处理
该拦截器对请求进行拦截处理后还要调用其他的拦截器,或者是业务处理器去进行处理,则返回true
不需要再调用其他的组件去处理请求,则返回false
postHandle()
modelandview 之后执行
在业务处理器处理完请求后,但是DispatcherServlet 向客户端返回响应前被调用,在该方法中对用户请求request进行处理
afterCompletion()
在 DispatcherServlet 完全处理完请求后被调用,可以在该方法中进行一些资源清理的操作
单个拦截器方法执行顺序
FirstInterceptor#preHandle
HandlerAdapter#handle
FirstInterceptor#postHanle
DispatcherServlet#render
FirstInterceptor#afterCompletion
实验案例:配置两个拦截器
SpringMVC.xml配置
<mvc:interceptors>
<bean class="org.xinzhang.myinterceptor.FirstInterceptor"/>
<mvc:interceptor>
<mvc:mapping path="/testJson"/>
<bean class="org.xinzhang.myinterceptor.SecondInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
<mvc:interceptors>
<bean class="org.xinzhang.myinterceptor.FirstInterceptor"/>
<mvc:interceptor>
<mvc:mapping path="/testJson"/>
<bean class="org.xinzhang.myinterceptor.SecondInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
两个拦截器的preHandle都返回true
第一个拦截器的 preHandle
第二个拦截器的 preHandle
第二个拦截器的 postHandle
第一个拦截器的 postHandle
第二个拦截器的 afterCompletion
第一个拦截器的 afterCompletion
第二个拦截器的 preHandle
第二个拦截器的 postHandle
第一个拦截器的 postHandle
第二个拦截器的 afterCompletion
第一个拦截器的 afterCompletion
当有多个拦截器时
preHandle:按照拦截器数组的正向顺序执行
postHandle:按照拦截器数组的反向顺序执行
afterCompletion:按照拦截器数组的反向顺序执行
第一个拦截器为true,第二个为false
第一个拦截器的 preHandle
第二个拦截器的 preHandle
第一个拦截器的 afterCompletion
第二个拦截器的 preHandle
第一个拦截器的 afterCompletion
两个(全部)拦截器的preHandle都会执行
但是(全部)postHandle都不会执行,而afterCompletion只有第一个(返回false的拦截器之前的所有afterCompletion)会执行
第一个拦截器为false
第一个拦截器的 preHandle
只有第一个preHandle会执行
spring和springMVC的整合
不整合
需要将spring所管理的内容都交给springMVC管理,(扫描组件,数据源,事务管理器)这样会造成业务逻辑混乱
整合
spring的配置文件什么时候加载?怎么加载?
通常情况下, 类似于数据源, 事务, 整合其他框架都是放在 Spring 的配置文件中(而不是放在 SpringMVC 的配置文件中)
实际上放入 Spring 配置文件对应的 IOC 容器中的还有 Service 和 Dao
实际上放入 Spring 配置文件对应的 IOC 容器中的还有 Service 和 Dao
监听器,可以在ServletContext加载时,通过监听器加载spring的配置文件,创建spring容器
spring提供的监听器:ContextLoaderListener
web.xml中
SpringMVC设置核心控制器
Spring的监听器
Spring来管理对象,处理事务等
把Spring和SpringMVC的配置文件分开
bean被创建两次的问题
在springMVC中只扫描控制层,在spring中,通过包含或排除对所扫描的包进行指定
SpringMVC处理请求与响应
spring和springMVC的关系
spring是父容器
springMVC是子容器
springMVC spring
controller-----service-----dao
controller-----service-----dao
规定:子容器能够调用访问父容器中的bean,而父容器不能够调用访问子容器中的bean
0 条评论
下一页