springMVC学习(二)工作流程

springMVC工作流程

  • 用户发送请求,请求交由SpringMVC核心控制器处理

  • 核心控制器找到映射器看该请求是否交由对应的Action类进行处理

  • 核心控制器再找到适配器看有无该Action类

  • Action类处理完业务之后返回一个ModelAndView对象

  • 最后通过视图解析器来对ModelAndView进行解析,跳转到对应的JSP/html页面

img

 

核心控制器

在web.xml中配置DispatcherServlet

SpringMVC配置文件的默认路径是WEB-INF下面,且配置文件的name默认应该是你配置的DispatcherServlet的servlet-name+servlet.xml(即DispatcherServlet-servlet.xml)

  • 如果配置文件放在WEB-INF目录下,但是name不是默认格式,可以通过namespace这个初始化参数进行指定

    <init-param>
<!-- 如果springmvc的配置文件springmvc.xml放在WEB-INF目录下,
但名字的形式不是*-servlet.xml,则可以通过namespace属性值进行指定 -->
<param-name>namespace</param-name>
<param-value>springmvc</param-value>
</init-param>
  • 如果配置文件不在WEB-INF目录下,则通过contextConfigLocation这个初始化参数进行指定位置和文件名

    <!--到类目录下寻找我们的配置文件applicationContext.xml-->
   <init-param>
     <param-name>contextConfigLocation</param-name>
     <param-value>classpath:applicationContext.xml</param-value>
   </init-param>
  • SpringMVC过滤编码器在web.xml配置文件中设置过滤编码器,该过滤编码器只能解决POST的乱码问题

  <!--编码过滤器-->
 <filter>
   <filter-name>characterEncodingFilter</filter-name>
   <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
   <init-param>
     <param-name>encoding</param-name>
     <param-value>utf-8</param-value>
   </init-param>
 </filter>
 <!--过滤所有请求-->
 <filter-mapping>
   <filter-name>characterEncodingFilter</filter-name>
   <url-pattern>/*</url-pattern>
 </filter-mapping>
  • 防止jsp中的静态中文乱码,在jsp首行设置编码格式 utf-8

<%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="utf-8" %>

映射器 HandlerMapping

handlerMapping获取到执行请求的Controller类和执行方法

  • 在web.xml中配置规定只要是.action为后缀的请求都是会经过SpringMVC的核心Servlet

  • 当我们接收到请求的时候,我们发现是hello.action,是会经过我们的核心Servlet的,那么核心Servlet就会去找有没有专门的Action类来处理hello.action请求的

  • 在applicationContext.xml中name属性就是规定了hello.action到HelloAction控制器中处理

映射器默认的值是这样的:

  <!-- 注册映射器(handler包)(框架)【可省略】 -->
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
</bean>

在创建控制器的时候可以不使用name属性来指定路径,可以使用映射器来配置。如以下的代码

    <bean class="HelloAction" id="helloAction"></bean>

   <!-- 注册映射器(handler包)(框架) -->
   <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
       <property name="mappings">
           <props>
               <prop key="/hello.action">helloAction</prop>
<!--当我们需要多个请求路径都交由helloAction控制器来处理的话,我们只要添加prop标签就行了!-->                <prop key="/bye.action">helloAction</prop>
           </props>
       </property>
   </bean>

适配器 HandlerAdapter

根据handlerMapping传过来的controller与已经注册好了的HandlerAdapter一一匹配,看哪一种HandlerAdapter是支持该controller类型的

当我们映射器找到对应的Action来处理请求的时候,核心控制器会让适配器去找该类是否实现了Controller接口【默认可省略的】

    <!-- 适配器【可省略】 -->
   <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>

视图解析器

我们把结果封装到ModelAndView以后,SpringMVC会使用视图解析器来对ModelAndView进行解析。【真实路径时,默认可省略的】

如果我们用的是逻辑路径(只有文件名,没有后缀),那么就必须对其配置,否则SpringMVC是找不到对应的路径的,如果用逻辑路径,就需要在applicationContext.xml中添加视图解析器

  • 如果Action中写的是视图逻辑名称,那么视图解析器就必须配置

  • 如果Action中写的是视图真实名称,那么视图解析器就可选配置

    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
       <!-- 路径前缀 -->
       <property name="prefix" value="/"/>
       <!-- 路径后缀 -->
       <property name="suffix" value=".jsp"/>
       <!-- 前缀+视图逻辑名+后缀=真实路径 -->
   </bean>

控制器

Handler,是对Controller的Bean本身和请求Method的包装。而HandlerExecutionChain 是handler的二次包装,将handler与拦截器链关联到了一起。然后,在DispatcherServlert中完成了拦截器链对handler的过滤。

映射器和适配器

  • 映射器

    • SpringMVC默认提供了两种HandlerMapping:BeanNameUrlHandlerMapping、DefaultAnnotationHandlerMapping

    • HandlerMapping的任务就是建立url与Bean(Controller)的对应关系,并将对应关系保存在handlerMap中

  • 适配器

    • DispatcherServlte会根据配置文件信息注册HandlerAdapter,如果在配置文件中没有配置,那么DispatcherServlte会获取HandlerAdapter的默认配置,如果是读取默认配置的话,DispatcherServlte会读取DispatcherServlte.properties文件,该文件中配置了三种HandlerAdapter:HttpRequestHandlerAdapter,SimpleControllerHandlerAdapter和AnnotationMethodHandlerAdapter。DispatcherServlte会将这三个HandlerAdapter对象存储到它的handlerAdapters这个集合属性中,这样就完成了HandlerAdapter的注册。

    • DispatcherServlte会根据handlerMapping传过来的controller与已经注册好了的HandlerAdapter一一匹配,看哪一种HandlerAdapter是支持该controller类型的,如果找到了其中一种HandlerAdapter是支持传过来的controller类型,那么该HandlerAdapter会调用自己的handle方法,handle方法运用Java的反射机制执行controller的具体方法来获得ModelAndView,例如SimpleControllerHandlerAdapter是支持实现了controller接口的控制器,如果自己写的控制器实现了controller接口,那么SimpleControllerHandlerAdapter就会去执行自己写控制器中的具体方法来完成请求

  • 映射器和适配器的对应关系

    • AnnotationMethodHandlerAdapter主要是适配注解类处理器,注解类处理器就是我们经常使用的@Controller的这类处理器

    • HttpRequestHandlerAdapter主要是适配静态资源处理器,静态资源处理器就是实现了HttpRequestHandler接口的处理器,这类处理器的作用是处理通过SpringMVC来访问的静态资源的请求。

    • SimpleControllerHandlerAdapter是Controller处理适配器,适配实现了Controller接口或Controller接口子类的处理器,比如我们经常自己写的Controller来继承MultiActionController,那么自己写的这些Controller就会由SimpleControllerHandlerAdapter来适

    • SimpleServletHandlerAdapter是Servlet处理适配器,适配实现了Servlet接口或Servlet的子类的处理器,我们不仅可以在web.xml里面配置Servlet,其实也可以用SpringMVC来配置Servlet,不过这个适配器很少用到,而且SpringMVC默认的适配器没有他,默认的是前面的三种。

 

posted @ 2020-12-20 18:03  huiyii  阅读(67)  评论(0编辑  收藏  举报