SpringMVC
-
三大组件
- Servlet
- Filter
- Listener
-
启动时执行,启动顺序
-
- ServletContextListener
-
- Filter
-
- Servlet
-
-
启动过程
- ServletContextListener 只执行一次,在Servlet创建和销毁时调用
- Listener
- Filter 过滤器 会在每次执行Servlet前后调用
- Servlet
-
设置字符集 过滤器
- charsetEncoding=UTF-8
- 遇到的问题
-
- Tomcat [信息]不是浣°C,是IDEA控制台的问题,设置vm Option -Dfile.encoding=UTF-8
-
- SpringMVC测试 get和post在没有过滤器的情况下都正常,post请求可能使用了thymeleaf模板发送,本身就是正常的字符集
-
- 需要设置好Encoding=UTF-8
-
- forceResponseEncoding=true
-
- 以上两个是根据源码确定的参数变量由CharaterEncoding确定
-
域对象
-
page域对象
- jsp独有,略过
-
request域对象
- 一次请求周期
-
session域对象
- 浏览器打开到关闭的周期(只和浏览器有关系)
-
ServletContext域对象
- 服务器打开到关闭(只和服务器有关)
-
域对象引发的问题
- 钝化和活化
- 钝化
- session 未结束,Servlet结束了,session会被序列化到磁盘
- 活化
- session 未结束,Servlet结束后又打开了连接,活化
- 钝化
- 钝化和活化
-
域对象使用原则
- 尽量合适,不一定大,也不一定小
-
ModelMap Model Map关系
- Model接口
- ModelMap -> linkedHashMap -> map
- BindingAwareModelMap -> ExtendedModelMap -> ModelMap/实现 Model
- Map接口
-
向Session域中共享变量
- Session HttpSession
- session.setAttribute(xxx,yy);
- @SessionAttribute注解,将请求域的数据共享到Session域
-
向Servlet域中共享变量
- 使用session.getServletContext
- servletContext.getAttribute()
-
-
视图解析器
- ThymeleafView
- 设置视图解析器后默认为Thymeleaf模板,拼装后由ThymeleafView => 转发
- RedirectView
- 重定向视图返回"redirect:/testxxx"
- InternalResourceView
- 转发视图返回"forward:/testxx"
- 数据转发forwar:/
- 数据转发需要进入Controller中的接口,而不能访问WebINf下的文件
- 因为WEB-INF目录不能直接转发
- 转发和重定向
- request对象不一致
- 转发一次请求 两个页面View 重定向两个请求,两个页面
- 转发不可以跨域 重定向可以访问
- ThymeleafView
-
拦截器自定义
-
SpringMVC的拦截器执行过程封装在DispatcherServlet中
- applyPreHandle 执行前执行
- applyPostHandle 执行后执行
- triggerAfterCompletion mv渲染后执行
-
自定义一个拦截器的过程(默认对所有进行拦截)
-
- SpringMVC配置文件声明
<mvc:interceptors> <bean class="com.kobe.interceptor.TestInterceptor"/> </mvc:interceptors>
-
- implements实现HandlerInterceptorj接口,并实现方法
- preHandle 方法前执行 返回值为false则拦截不通行
- postHandle 方法后执行
- afterCompletion 结束后执行
-
- 指定拦截路径进行拦截
- 配置文件,包括所有路径,排除一个路径
<mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/*"/> <mvc:exclude-mapping path="/success"/> <ref bean="testInterceptor"/> </mvc:interceptor> </mvc:interceptors>
-
- 配置的执行顺序
- 配置执行顺序,顺序执行preHandle
- 配置执行顺序,逆序执行postHandle、afterCompletion
-
-
-
DispatcherServlet的组件(常用的、总共九个)
- DispatcherServlet: 前端控制器 负责分发
- HandleMapping :处理器映射器 负责组织成一个链,包括多个部分,如拦截器 映射等
- Handler:处理器 具体业务
- HandleAdapter:处理器适配器 执行业务mv = ha.()
- ViewResolver:视图解析器 将MV转化成视图 ThymeLeaf forward:/ -> InternalViewResourceView redirect:/ ->RedirectView
- View:视图 将模型数据通过页面展示给用户
-
DispatcherServlet 初始化过程
-
-
Servlet init
-
GenicServlet重写init(Servlet Config)
-
HttpServlet没有init方法
-
ServletBean重写GenicServlet的init方法,同时写出initServletBean方法
-
FrameworkServlet重写initServletBean方法,同时写出initFrameworkServlet方法,在这个时候初始化
-
onRefreash 给子类调用,DispatcherServlet重写了onRefreash -> initStrategies(context)
-
在DispatcherServlet中使用initStrategies 初始化 ,初始化了9大组件,加载完成
protected void initStrategies(ApplicationContext context) { initMultipartResolver(context); initLocaleResolver(context); initThemeResolver(context); initHandlerMappings(context); initHandlerAdapters(context); initHandlerExceptionResolvers(context); initRequestToViewNameTranslator(context); initViewResolvers(context); initFlashMapManager(context); }
-
-
-
DispatcherServlet服务提供的过程
-
- GenicServlet service 没有具体业务实现
- HttpServlet service 将GenicServlet中的ServletRequest req 提升为HttpServletRequest req Response同理,重载了service方法,放入的是HttpServletRequest和Http对应的Response
- HttpServletBean并没有service方法
- FrameworkServlet实现了service方法,并实现了各类的doGet doPost但是都指向了一个函数 -> processRequest
- processRequest 需要调用doService方法,doService方法是一个抽象方法,在子类的DispatcherServlet中实现
- DispatcherServlet中的doService方法主要调用了doDispatch方法,这个方法完成了整个业务流程
-
-
DispatcherServlet服务组件调用全过程
-
- request -> processRequest
- HandlerExecutionChain - > 装载到mappedHandler getHandler函数执行(整个执行链)
- 将执行链转化到处理器适配器RequestMappingHandlerAdapter 的HandlerAdapter,通过getHandlerAdapter将执行链转化到适配器(寻找在RequestMapping中的方法,并调用控制器方法)
- 在ha.handle -> 执行了很多内容,其中Controller中的形参赋值、数据类型转换,收集请求参数,形参中使用ServletApi、数据验证、MessageConvert等等
- 调用postHandle方法执行拦截器
- 执行processDispatchResult -> 渲染视图ViewResolver(包括存在异常页面数据处理)
- 执行mapperHandler.triggerAfterCompletion方法 执行拦截器执行后的方法,利用索引倒序执行
-