SpringMVC笔记

SpringMVC

  • 三大组件

    • Servlet
    • Filter
    • Listener
  • 启动时执行,启动顺序

      1. ServletContextListener
      1. Filter
      1. Servlet
  • 启动过程

    • ServletContextListener 只执行一次,在Servlet创建和销毁时调用
    • Listener
    • Filter 过滤器 会在每次执行Servlet前后调用
    • Servlet
  • 设置字符集 过滤器

    • charsetEncoding=UTF-8
    • 遇到的问题
      1. Tomcat [信息]不是浣°C,是IDEA控制台的问题,设置vm Option -Dfile.encoding=UTF-8
      1. SpringMVC测试 get和post在没有过滤器的情况下都正常,post请求可能使用了thymeleaf模板发送,本身就是正常的字符集
      1. 需要设置好Encoding=UTF-8
      1. forceResponseEncoding=true
      1. 以上两个是根据源码确定的参数变量由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 重定向两个请求,两个页面
      • 转发不可以跨域 重定向可以访问
  • 拦截器自定义

    • SpringMVC的拦截器执行过程封装在DispatcherServlet中

      • applyPreHandle 执行前执行
      • applyPostHandle 执行后执行
      • triggerAfterCompletion mv渲染后执行
    • 自定义一个拦截器的过程(默认对所有进行拦截)

        1. SpringMVC配置文件声明
          <mvc:interceptors>
              <bean class="com.kobe.interceptor.TestInterceptor"/>
          </mvc:interceptors>
      
        1. implements实现HandlerInterceptorj接口,并实现方法
        • preHandle 方法前执行 返回值为false则拦截不通行
        • postHandle 方法后执行
        • afterCompletion 结束后执行
        1. 指定拦截路径进行拦截
        • 配置文件,包括所有路径,排除一个路径
      <mvc:interceptors>
          <mvc:interceptor>
              <mvc:mapping path="/*"/>
              <mvc:exclude-mapping path="/success"/>
              <ref bean="testInterceptor"/>
          </mvc:interceptor>
      </mvc:interceptors>
      
        1. 配置的执行顺序
        • 配置执行顺序,顺序执行preHandle
        • 配置执行顺序,逆序执行postHandle、afterCompletion
  • DispatcherServlet的组件(常用的、总共九个)

    • DispatcherServlet: 前端控制器 负责分发
    • HandleMapping :处理器映射器 负责组织成一个链,包括多个部分,如拦截器 映射等
    • Handler:处理器 具体业务
    • HandleAdapter:处理器适配器 执行业务mv = ha.()
    • ViewResolver:视图解析器 将MV转化成视图 ThymeLeaf forward:/ -> InternalViewResourceView redirect:/ ->RedirectView
    • View:视图 将模型数据通过页面展示给用户
  • DispatcherServlet 初始化过程

      1. Servlet init

      2. GenicServlet重写init(Servlet Config)

      3. HttpServlet没有init方法

      4. ServletBean重写GenicServlet的init方法,同时写出initServletBean方法

      5. FrameworkServlet重写initServletBean方法,同时写出initFrameworkServlet方法,在这个时候初始化

        image-20211116094710192

      6. onRefreash 给子类调用,DispatcherServlet重写了onRefreash -> initStrategies(context)

      7. 在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服务提供的过程

      1. GenicServlet service 没有具体业务实现
      2. HttpServlet service 将GenicServlet中的ServletRequest req 提升为HttpServletRequest req Response同理,重载了service方法,放入的是HttpServletRequest和Http对应的Response
      3. HttpServletBean并没有service方法
      4. FrameworkServlet实现了service方法,并实现了各类的doGet doPost但是都指向了一个函数 -> processRequest
      5. processRequest 需要调用doService方法,doService方法是一个抽象方法,在子类的DispatcherServlet中实现
      6. DispatcherServlet中的doService方法主要调用了doDispatch方法,这个方法完成了整个业务流程
  • DispatcherServlet服务组件调用全过程

      1. request -> processRequest
      2. HandlerExecutionChain - > 装载到mappedHandler getHandler函数执行(整个执行链)
      3. 将执行链转化到处理器适配器RequestMappingHandlerAdapter 的HandlerAdapter,通过getHandlerAdapter将执行链转化到适配器(寻找在RequestMapping中的方法,并调用控制器方法)
      4. 在ha.handle -> 执行了很多内容,其中Controller中的形参赋值、数据类型转换,收集请求参数,形参中使用ServletApi、数据验证、MessageConvert等等
      5. 调用postHandle方法执行拦截器
      6. 执行processDispatchResult -> 渲染视图ViewResolver(包括存在异常页面数据处理)
      7. 执行mapperHandler.triggerAfterCompletion方法 执行拦截器执行后的方法,利用索引倒序执行
posted @ 2021-11-16 14:53  kobe96  阅读(27)  评论(0编辑  收藏  举报