springMVC详解

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了springMVC详解相关的知识,希望对你有一定的参考价值。

目录

[toc]

一、spring mvc 核心类与接口

DispatcherServlet -- 前置控制器

技术分享图片

HandlerMapping接口 -- 处理请求的映射

HandlerMapping接口的实现类:

SimpleUrlHandlerMapping 通过配置文件,把一个URL映射到Controller

DefaultAnnotationHandlerMapping || RequestMappingHandlerMapping 通过注解,把一个URL映射到Controller

HandlerAdapter 接口 -- 处理请求的映射

AnnotationMethodHandlerAdapter || RequestMappingHandlerAdapter 通过注解,把一个URL映射到Controller类的方法上

Controller接口 -- 控制器

由于我们使用@Controller注解,添加了该注解的类就可以担任控制器(action)的职责

HandlerInterceptor 接口 -- 拦截器

我们自己实现这个接口,来完成拦截器的工作

ViewResolver接口的实现类

UrlBasedViewResolver类 通过配置文件,把一个视图名交给到一个View来处理

InternalResourceViewResolver类,比上面的类,加入了JSTL的支持

技术分享图片

HandlerExceptionResolver 接口 -- 异常处理接口

二、spring mvc 核心流程图[流程图]

技术分享图片

三、DispatcherServlet说明

使用spring mvc,配置的第一步就是DispatcherServlet

DispatcherServlet是一个servlet,所以可以配置多个servlet。DispatcherServlet是前置控制器,配置在web.xml中。拦截配置的所有请求,servlet拦截规则需要自己定义,把拦截下来的请求根据某某规则分发到我们自己定义的controller的method中处理。

某某规则:是根据在spring mvc.xml文件里面配置的handlerMapping接口的实现类不同而不同

 <servlet>
   <servlet-name>mvc-dispatcher</servlet-name>
   <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
   <init-param>
     <param-name>contextConfigLocation</param-name>
     <param-value>classpath:/META-INF/spring/mvc-servlet.xml</param-value>
   </init-param>
   <!--启动顺序,让这个Servlet随Servletp容器一起启动-->
   <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
  <servlet-name>mvc-dispatcher</servlet-name>
  <url-pattern>/</url-pattern>
</servlet-mapping>

表示这个servlet的名字是mvc-dispatcher,可以有多个DispatcherServlet,通过名字来区分,每个DispatcherServlet都有自己的WebApplicationContext上下文对象,同时保存的ServletContext中和Request对象中。

在DispatcherServlet的初始化过程中,框架会在web应用的web-INF文件夹下寻找名为[servlert-name]-servlet.xml的配置文件,生成文件中定义的bean。当在中指明了配置文件的文件名时,则使用该配置文件。

其中这里有多种可使用写法

1、不写,使用默认值: /WEB-INF/

2、

3、

4、多个值用英文豆粉分隔

4、springMVC.xml配置文件片段讲解(未使用默认配置文件名)

<?xml version="1.0" encoding="UTF-8"?>  
<beans  
    xmlns="http://www.springframework.org/schema/beans"  
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
    xmlns:tx="http://www.springframework.org/schema/tx"  
    xmlns:context="http://www.springframework.org/schema/context"     
    xmlns:mvc="http://www.springframework.org/schema/mvc"     
    xsi:schemaLocation="http://www.springframework.org/schema/beans    
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd    
    http://www.springframework.org/schema/tx    
    http://www.springframework.org/schema/tx/spring-tx-3.0.xsd   
    http://www.springframework.org/schema/context   
    http://www.springframework.org/schema/context/spring-context-3.0.xsd   
    http://www.springframework.org/schema/mvc   
    http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">  
  
  
    <!-- 自动扫描的包名 -->  
    <context:component-scan base-package="com.app,com.core,JUnit4" ></context:component-scan>  
       
    <!-- 默认的注解映射的支持 -->  
    <mvc:annotation-driven />  
       
    <!-- 视图解释类 -->  
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">  
        <property name="prefix" value="/WEB-INF/jsp/"/>  
        <property name="suffix" value=".jsp"/><!--可为空,方便实现自已的依据扩展名来选择视图解释类的逻辑  -->  
        <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />  
    </bean>  
       
    <!-- 拦截器 -->  
    <mvc:interceptors>  
        <bean class="com.core.mvc.MyInteceptor" />  
    </mvc:interceptors>        
       
    <!-- 对静态资源文件的访问  方案一 (二选一) -->  
    <mvc:default-servlet-handler/>  
       
    <!-- 对静态资源文件的访问  方案二 (二选一)-->  
    <mvc:resources mapping="/images/**" location="/images/" cache-period="31556926"/>  
    <mvc:resources mapping="/js/**" location="/js/" cache-period="31556926"/>  
    <mvc:resources mapping="/css/**" location="/css/" cache-period="31556926"/>  
 
</beans>   

@Controller 声明Action组件

@Service 声明service组件

@Repository 声明Dao组件

@Component 泛指组件,不好归类

@RequestMapping("/index") 请求映射

@Resource 用于注入,(j2ee提供)默认按名称装配,@Resource(name="beanName")

@Autowired 用于注入,(spring)提供,默认按类型装配

@Transactional( rollbackFor={Exception.class}) 事务管理

使用

5、请求如何映射到具体的Action方法?

这里只讲基于注解的映射:可以使用DefaultAnnotationHandlerMapping || RequestMappingHandlerMapping

<!-- 请求映射 Handler,把一个url映射到controller类上 -->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping">
            <!-- 拦截器 -->    
            <property name="interceptors">  
            <list>  
                <bean />
            </list>  
        </property>  
    </bean>

<bean id="stringHttpMessageConverter" class="org.springframework.http.converter.StringHttpMessageConverter" /> 
    
    <bean id="jsonHttpMessageConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter" />

    <!-- Handler 适配器配置, 通过注解,把一个url映射到controller类的方法上,执行真实页面处理器的处理请求 -->
    <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
        <property name="messageConverters">
            <list>
                <ref bean="stringHttpMessageConverter"/>
                <ref bean="jsonHttpMessageConverter"/>
            </list>
        </property>
    </bean>

在Controller类上使用@Controller,@RequestMapping("/home"),在method上使用@RequestMapping("/index")。当http请求请求发送到服务端会根据url来查找应该执行哪个controller下面的哪个action,我理解为url为java代码的一个路由关系。

spring mvc 的核心类 DispatcherServlet在初始化时会初始化HandlerMapping与HandlerAdaper,

HandlerMapping主要是调用BeanFactoryUtils.beansOfTypeIncludingAncestors,其中一种是非常重要的HandlerMapping是RequestMappingHandlerMapping,我们通过在controller方面上加@RequestMapping注释来配合使用,系统会将我们配置的RequestMapping信息注册到其中。mappingRegistry中包含有所有的路由信息。
技术分享图片

代码如下:


  private void initHandlerMappings(ApplicationContext context) {
        this.handlerMappings = null;

        if (this.detectAllHandlerMappings) {
            // Find all HandlerMappings in the ApplicationContext, including ancestor contexts.
            Map<String, HandlerMapping> matchingBeans =
                    BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerMapping.class, true, false);
            if (!matchingBeans.isEmpty()) {
                this.handlerMappings = new ArrayList<HandlerMapping>(matchingBeans.values());
                // We keep HandlerMappings in sorted order.
                AnnotationAwareOrderComparator.sort(this.handlerMappings);
            }
        }
        //不加载全部的先省略

        //加载默认的逻辑先省略
    }

DispatcherServlet核心方法:doDispatch,三个重要步骤:

  • getHandler,获取页面处理器,通俗点就是获取由哪个Controller来执行,包含方法信息以及方法参数等信息。

  • getHandlerAdapter,获取HandlerAdapter,它包含一个handle方法,负责调用真实的页面处理器进行请求处理并返回一个ModelAndView。HandlerAdpter里面有一些常见的处理,比如消息转移,参数处理等,详见此图:里面的argumentResolvers可以用来处理请求的参数,messageConverts是作消息转换等等。
    技术分享图片

  • HandlerAdapter.handle,执行真实页面处理器的处理请求

?

6、Spring中的拦截器

spring为我们提供了

org.springframework.web.servlet.HandlerInterceptor接口

org.springframework.web.servlet.handler.HandlerInterceptorAdapter适配器

实现这个接口或者继承这个适配器类,可以非常方便的实现自己的拦截器

拦截器中有以下三个方法

action前执行:

public boolean preHandle();

生成视图前执行

public void postHandle();

最后执行,可用于释放资源

public void afterCompletion();

分别用于实现预处理、后处理(调用了method并返回了ModelAndView,但还未进行页面渲染)、返回处理(页面已渲染)

在preHandle()中可以进行编码、安全处理、拦截请求等操作、

在postHandle()中有机会修改ModelAndView、

在postHandle()中可以根据ex判断是否发生了异常

使用拦截器

自定义一个拦截器,要实现HandlerInterceptor接口或继承HandlerInterceptorAdapter适配器

方案一、

<mvc:interceptors>   
    <bean class="com.app.mvc.MyInteceptor" />   
</mvc:interceptors> 

方案二、

<mvc:interceptors >     
  <mvc:interceptor>     
        <mvc:mapping path="/user/*" /> <!-- /user/*  -->     
        <bean class="com.mvc.MyInteceptor"></bean>     
    </mvc:interceptor>     
</mvc:interceptors>   

spring没有总的拦截器,不过在springmvc的配置文件里使用

方案三 handlerMapping上的拦截器、

<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">        
 <property name="interceptors">        
     <list>        
         <bean class="com.mvc.MyInteceptor"></bean>       
     </list>        
 </property>        
</bean>

使用这种风格的拦截器不会拦截静态资源,因为精准的注入了拦截器。

如果是使用

七、如何实现全局的异常处理?



以上是关于springMVC详解的主要内容,如果未能解决你的问题,请参考以下文章

(转) Java中的负数及基本类型的转型详解

详解Android WebView加载html片段

axis2+springmvc详解

SpringMvc 文件下载 详解

Spring/Boot/Cloud系列知识:SpringMVC 传参详解(下)

Spring/Boot/Cloud系列知识:SpringMVC 传参详解(下)