SpringMVC之DispacherServlet

1.DispacherServlet是前端控制器(Struts是Filter),负责接收前端请求,并根据请求找到具体的Handler(目前的Handler是方法级别的);SpringMVC中DispacherServlet初始化放在web.xml中,<load-on-start>1</load-on-start>,意思是Servlet容器启动时自动加载该Servlet。

2.HandlerMapping:负责将URL和controller匹配到一起,简单来说就是根据URL找到具体的类(根据注解@Controller和@RequestMapping找到);

3.HandlerAdapter:根据URL找到具体类的具体方法;

  jdk 具体执行过程如下:

  1.DispatcherServlet本质上还是一个Servlet,故需要在web容器里初始化

/**
     * Initialize the strategy objects that this servlet uses.
     * <p>May be overridden in subclasses in order to initialize further strategy objects.
     */
    protected void initStrategies(ApplicationContext context) {
        initMultipartResolver(context);
        initLocaleResolver(context);
        initThemeResolver(context);
        initHandlerMappings(context); // 从ApplicationContext容器中初始生成HandlerMappings
        initHandlerAdapters(context); // 初始化HandlerAdapter
        initHandlerExceptionResolvers(context);
        initRequestToViewNameTranslator(context);
        initViewResolvers(context);
        initFlashMapManager(context);
    }

2.当有一个请求到达时,调用DispatcherServlet的doDispatch()方法,该方法找到真正的handler处理该请求;主要代码如下:

/**
     * Process the actual dispatching to the handler.
     * <p>The handler will be obtained by applying the servlet‘s HandlerMappings in order.
     * The HandlerAdapter will be obtained by querying the servlet‘s installed HandlerAdapters
     * to find the first that supports the handler class.
     * <p>All HTTP methods are handled by this method. It‘s up to HandlerAdapters or handlers
     * themselves to decide which methods are acceptable.
     * @param request current HTTP request
     * @param response current HTTP response
     * @throws Exception in case of any kind of processing failure
   *       通过查找HandlerMapping找到真正的Handler;先找到handler class,根据该class找到HandlerAdapter;       通过查询servlet已注册的HandlerAdapters,找到真正处理该请求的method
     */
    protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
        HttpServletRequest processedRequest = request;
        HandlerExecutionChain mappedHandler = null;
        boolean multipartRequestParsed = false;

            ModelAndView mv = null;
           // Determine handler for the current request.返回HandlerExecutionChain;
           mappedHandler = getHandler(processedRequest, false);
      // Determine handler adapter for the current request.根据HandlerExecutionChain找到HandlerAdapter
      HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
    
      // Actually invoke the handler.使用给定的handler处理请求;
      mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

    }
protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
        for (HandlerMapping hm : this.handlerMappings) {
            if (logger.isTraceEnabled()) {
                logger.trace(
                        "Testing handler map [" + hm + "] in DispatcherServlet with name ‘" + getServletName() + "‘");
            }

    //查询所有已注册的HandlerMapping beans找到处理该请求的Handler;
            HandlerExecutionChain handler = hm.getHandler(request);
            if (handler != null) {
                return handler;
            }
        }
        return null;
    }
其中HandlerExecutionChain是有一个HandlerAdapter和若干个HandlerInteceptor组成,请求先经HandlerInteceptor处理后在传给Adapter。一般我们使用HandlerInteceptor做一些登录验证,安全验证等

3.HandlerInterceptor和Servlet里的Filter作用很像,下面讲一下关于Filter的东西

  3.1  Filter作用?

    用于HttpServletRequest预处理和HttpServletResponse后处理;执行流程是 request---->listener----->filter------>struts拦截器(?)----->Servlet,这是链式处理过程,请求最后总会到达Servlet的;

  3.2 一般用来干啥?

    用户登录验证,用户发来请求,拦截请求后,验证用户是否登录过,如果没有登录调到登录页面;日志功能;编码格式

  3.3Filter有三个过程

    Filter一般在服务器端工作,故web容器调用它的init(),在web容器初始化的时候创建Filter的实例对象;

    chain.doFilter(),把要做的事情都放在doFilter()方法里面完成;

  3.4 filter使用配置文件注册,在web应用程序一启动,web服务器就会实例化filter对象;

    filter实例化

    web.xml配置:   

<!-- 编码过滤器 -->
    <filter>
        <filter-name>setCharacterEncoding</filter-name>
        <filter-class>com.company.strutstudy.web.servletstudy.filter.EncodingFilter</filter-class>  //该过滤器(EncodingFilter)具体位置。
        <init-param>
            <param-name>encoding</param-name>   // 设定encoding编码为utf-8.
            <param-value>utf-8</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>setCharacterEncoding</filter-name>
        <url-pattern>/*</url-pattern>    //处理所有页面的编码格式
    </filter-mapping>  

<!-- 请求url日志记录过滤器 -->
    <filter>
        <filter-name>logfilter</filter-name>
        <filter-class>com.company.strutstudy.web.servletstudy.filter.LogFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>logfilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>  

    编码拦截器:

public class EncodingFilter implements Filter {
    private String encoding;
    private Map<String, String> params = new HashMap<String, String>();
    // 项目结束时就已经进行销毁
    public void destroy() {
        System.out.println("end do the encoding filter!");
        params=null;
        encoding=null;
    }
    public void doFilter(ServletRequest req, ServletResponse resp,
            FilterChain chain) throws IOException, ServletException {
        //UtilTimerStack.push("EncodingFilter_doFilter:");
        System.out.println("before encoding " + encoding + " filter!");
        req.setCharacterEncoding(encoding);
        // resp.setCharacterEncoding(encoding);
        // resp.setContentType("text/html;charset="+encoding);
        chain.doFilter(req, resp);
        System.out.println("after encoding " + encoding + " filter!");
        System.err.println("----------------------------------------");
        //UtilTimerStack.pop("EncodingFilter_doFilter:");
    }  

    // 项目启动时就已经进行读取
    public void init(FilterConfig config) throws ServletException {
        System.out.println("begin do the encoding filter!");
        encoding = config.getInitParameter("encoding");
        for (Enumeration e = config.getInitParameterNames(); e
                .hasMoreElements();) {
            String name = (String) e.nextElement();
            String value = config.getInitParameter(name);
            params.put(name, value);
        }
    }
 }  

时间: 2024-08-30 09:27:07

SpringMVC之DispacherServlet的相关文章

Spring以及SPringmvc相关问题: ServletContext -父子容器

总结如下: 明确了Servlet规范中ServletContext的作用和意义.此外明确一个Tomcat中多个web应用,每个人web应用有唯一的一个ServletContext(全局上下文).[例子见:同一tomcat多个应用session问题] 这个ServletContext 对应JSP中内置对象javax.servlet.jsp.ServletContext(作用于application全局级) 明确Spring(Spring.context包定义)上下文 ApplicationCont

【转载】SpringMVC配置文件详解

转自:https://my.oschina.net/happyBKs/blog/691502 web.xml文件是web应用的部署描述. 在上一节的springMVC示例中 ,idea下的Maven-webapp项目自动生成了web.xml文件,用的是webapp2.3的标准.文件头声明如下: <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http:/

零配置文件搭建SpringMVC实践纪录

本篇记录使用纯java代码搭建SpringMVC工程的实践,只是一个demo.再开始之前先热身下,给出SpringMVC调用流程图,讲解的是一个http request请求到达SpringMVC框架后的过程,如下: 从servlet 3.0开始,实现javax.servlet.ServletContainerInitializer接口的类将在容器启动的时候执行onStartup方法.SpringMVC的”零配置”就是基于这个特性.所以对于servlet 3.0 以下的容器还是老老实实在web.x

SpringMVC 应用配置

1.增加Spring的支持 新建web项目,添加如下jar包: commons-logging-1.2.jar spring-aop-4.2.5.RELEASE.jar spring-aspects-4.2.5.RELEASE.jar spring-beans-4.2.5.RELEASE.jar spring-context-4.2.5.RELEASE.jar spring-context-support-4.2.5.RELEASE.jar spring-core-4.2.5.RELEASE.j

springMVC容器加载源码分析

springmvc是一个基于servlet容器的轻量灵活的mvc框架,在它整个请求过程中,为了能够灵活定制各种需求,所以提供了一系列的组件完成整个请求的映射,响应等等处理.这里我们来分析下springMVC的源码. 首先,spring提供了一个处理所有请求的servlet,这个servlet实现了servlet的接口,就是DispatcherServlet.把它配置在web.xml中,并且处理我们在整个mvc中需要处理的请求,一般如下配置: <servlet> <servlet-name

SpringMVC实现操作的第二种方式

一: 运行效果: 点击提交之后显示效果 二: (1).web.xml <?xml version="1.0" encoding="UTF-8"?> <web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi

SpringMVC基础配置(二)

上一张:SpringMVC环境搭建(一) 今天我们来说说SpringMVC的基础配置.目前越来越多的主流框架都支持注解,同时我们无敌的Spring也支持基于注解的"零配置". 注解相比XML的优势:它可以充分利用Java的反射机制获取类中的结构信息,这些信息可以有效减少配置的工作,注释和Java代码位于一个文件中,更加利于维护. 注意:必须要在Spring2.5版本之后才可以使用注解方式. 注解方式将Bean的定义信息和Bean的实现类结合在一起,Spring提供的注解有. @Comp

SpringMVC环境搭建之Idea

SpringMVC一.. SpringMVC重要组件介绍    1. DispacherServlet:前端控制器,接收所有请求,(如果配置/不包含jsp)    2. HandlerMapping:解析请求格式,判断希望要执行哪个方法    3. HandlerAdapter:负责调用具体的方法    4. ViewResovler:视图解析器,解析结果,准备跳转的具体的视图 spring的jar包官方下载地址: https://repo.spring.io/libs-release-loca

springmvc 的请求处理过程(精编)

1. DispacherServlet 前端控制器接受发送过来的请求,交给HandlerMapping 处理映射器, 2. HandlerMapping 处理映射器, 根据请求找到相应的HandlerAdapter 处理适配器(处理适配器就是那些拦截器活着吧Controller) 3. HandlerAdapter处理器适配器,处理一些功能请求, 返回一个ModleAndView 对象,包括模型数据.逻辑视图名. ViewResolver视图解析器 ,先根据ModleAndView 中设置的vi