资讯专栏INFORMATION COLUMN

SpringMVC之源码分析--HandlerAdapter(三)

Dionysus_go / 2576人阅读

摘要:概述回顾上两章,我们主要分析了的概念作业以及如何使用的组件,本节以及后续几章,将介绍为我们提供的的具体实现类,基于源码和设计层面进行介绍,欢迎大家关注。本系列文章是基于。

概述

回顾上两章,我们主要分析了HandlerAdapter的概念、作业以及Spring MVC如何使用的HandlerAdapter组件,本节以及后续几章,将介绍Spring为我们提供的HandlerAdapter的具体实现类,基于源码和设计层面进行介绍,欢迎大家关注。

本系列文章是基于Spring5.0.5RELEASE。

SimpleServletHandlerAdapter

SimpleServletHandlerAdapter适配器是Spring MVC提供的实现HandlerAdapter接口的最简单的一个,其功能就是对javax.servlet.Servlet进行适配,从其源码可知,在support方法中,判断我们的类是否是Servlet,也即是否继承Servlet类为条件来进行适配的,并且在handle方法中调用的service方法,源码如下:

public class SimpleServletHandlerAdapter implements HandlerAdapter {

    /**
     * 实现handler的匹配策略,此处以handler是否是Servlet子类进行的判断
     * 也就是说,判断我们的handler是否实现javax.servlet.Servlet接口或者继承其子类
     */
    @Override
    public boolean supports(Object handler) {
        return (handler instanceof Servlet);
    }
    
    /**
     * 请求处理方法,此处调用的是handler的service方法
     * 如果我们定义的handler直接实现了Servlet,那么需要实现其service方法
     * 但一般我们在进行Servlet编程时,并不直接实现此接口,而是继承HttpServlet抽象类,
     * 该抽象类实现了Servlet接口的service方法,我们的handler只需要根据需求,重写doGet、doPost等方法即可
     */
    @Override
    @Nullable
    public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        // 调用handler的service方法
        ((Servlet) handler).service(request, response);
        return null;
    }

    
    @Override
    public long getLastModified(HttpServletRequest request, Object handler) {
        return -1;
    }

}

以上就是SimpleSerlvetHandlerAdapter的源码,这是Spring使用HandlerAdapter最简单的方式,此方式是为了在Spring中支持Servlet方式开发,即把Servlet适配为处理器handler。

实战

好几篇文章没有写这部分了,其实每一篇文章我都有写过测试demo,但是由于篇幅问题,没有发布出去,本章内容较少,所以跟大家分享下如何验证以及验证的方法。

项目结构

在开发IDE中创建webapp项目,我使用的IDEA,用maven进行构建,最终的项目结构如下:

-- java目录是我们存放源代码的目录

-- resources是存放配置文件的目录,如spring-servlet.xml是Spring MVC的配置文件

-- webapp是存放静态资源以及view视图目录,其中/WEB-INF/web.xml是部署描述文件,在其内部配置Spring MVC的DispatcherServlet

项目源码

pom文件

由于我们使用maven进行构建,在其pom文件中加入项目依赖,就本项目我们需要添加Spring MVC的依赖,最终源码如下:




  4.0.0
  
  
  com.github.dalianghe
  spring-mvc-handleradapter
  1.0-SNAPSHOT
  war

  spring-mvc-handleradapter Maven Webapp
  
  http://www.example.com

  
    UTF-8
    1.8
    1.8
  

  
    
    
      org.springframework
      spring-webmvc
      5.0.5.RELEASE
    
    
    
      javax.servlet
      javax.servlet-api
      3.1.0
      provided
    
  

  
    spring-mvc-handlermapping
    
      
        
        
          org.apache.tomcat.maven
          tomcat7-maven-plugin
          2.2
          
            /
            8086
          
        
      
    
  

Spring MVC配置文件

目前我们是用的传统的基于xml配置的方式进行编程的,故需要创建一个Spring MVC的配置文件,用于初始化Spring MVC上下文以及配置策略,源码如下:




    
    
        
            
                servletController
            
        
    
    
    
    
    


本例我们使用的SimpleUrlHandlerMapping注册我们的handler的,也可以使用其他HandlerMapping进行注册。

部署描述文件

在web.xml中配置Spring MVC的DispatcherServlet,代码如下:



  Archetype Created Web Application

  
    
    dispatcher
    
    org.springframework.web.servlet.DispatcherServlet
    
    
      contextConfigLocation
      classpath:spring-servlet.xml
    
    
    1
    true
  
  
  
    
    dispatcher
    
    /
  


编写Handler

最后我们编写自己的Handler,根据SimpleServletHandlerAdatper要求,我们的Handler必须实现javax.servlet.Servlet接口,代码如下:

package com.github.dalianghe.controller;

import org.springframework.lang.Nullable;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.Writer;

/**
 * 本例我们继承HttpServlet抽象类,其内部实现了Servlet接口的service方法

         */
        public class ServletController extends HttpServlet{
        
            @Override
            protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
                Writer writer = resp.getWriter();
                writer.write("hello SimpleServletHandlerAdapter!");
                writer.flush();
            }
            
        }

至此,我们就编写完成了我们的代码,下面进行测试验证。

测试验证

我们配置使用了SimpleServletHandlerAdapter适配器,首先验证Spring MVC是不是使用我们配置的适配器,验证方法是在DispatcherServlet的initHandlerAdapters方法上打断点,然后启动,具体如下:

有图可知,Spring MVC确实使用的是我们配置的SimpleServletHandlerAdapter,验证通过。

接下来,我们验证用户请求是否使用的SimpleServletHandlerAdapter适配器进行的处理,在DispatcherServlet的doDispatch方法中打断点以及在我们的handler方法中打断点,并发起请求http://localhost:8086/servletController,结果如下图:

由以上可知,Spring MVC使用SimpleServletHandlerAdapter适配器把请求转发给我了我们的Handler。跳过断点,浏览器也会数据hello SimpleServletHandlerAdapter,如下图:

以上我们验证了正确的情况,作为验证肯定不完善,我们还要验证错误的用例,比如,我们的Handler不继承HttpServlet,即不实现Servlet接口,按照SimpleServletHandlerAdatper适配策略,应该找不到handler进行处理,我们来验证这个结果。

首先修改我们的Handler,去掉extends HttpServlet,然后重启应用再次访问,结果首先界面会显示500错误,并且后台也跑异常,如下图:

至此,我们完成了测试验证。

总结

本章主要分析了SimpleServletHandlerAdapter类源码以及开发了demo用于验证测试,验证测试覆盖了正常测试和异常测试,在实际的工作中,测试非常重要,不仅要测试正常情况也要对异常情况下进行测试,这样我们最大程度的确保我们开发的程序健壮。本章分析就这些,谢谢大家!

最后创建了qq群方便大家交流,可扫描加入,同时也可加我qq:276420284,共同学习、共同进步,谢谢!

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/69536.html

相关文章

  • SpringMVC源码分析--HandlerAdapter(二)

    摘要:概述本章我们主要分析处理组件的处理流程以及其接口源码。概括来说,使用组件分为两步,首先是注册组件,其次是处理用户请求,以下针对这两个过程进行详细的分析。本系列文章是基于。接下来的几章将分析提供的适配策略,希望本节对大家能有帮助,谢谢。 概述 本章我们主要分析Spring处理HandlerAdapter组件的处理流程以及其接口源码。概括来说,Spring使用HandlerAdapter组...

    Eastboat 评论0 收藏0
  • SpringMVC源码分析--HandlerAdapter(一)

    摘要:本系列文章是基于。说这么多就是想解释下什么是适配器。本节我们主要从整体以及概念上阐述了的,后续会逐个分析提供的四种适配器,希望本节对大家能有帮助,谢谢。最后创建了群方便大家交流,可扫描加入,同时也可加我,共同学习共同进步,谢谢 概述 本章开始,我们分析Spring MVC的另一个重要组件,即HandlerAdapter,从命名上我即可直观的理解为处理器适配器,那么处理器适配器是什么意思...

    dingda 评论0 收藏0
  • “过时”的SpringMVC我们到底在用什么?深入分析DispatchServlet源码

    摘要:问题来了,我们到底还在用吗答案是,不全用。后者是初始化的配置,主要是的配置。启动类测试启动项目后,在浏览器里面输入。通过查询已装载的,并且支持该而获取的。按照前面对的描述,对于而言,这个必定是。的核心在的方法中。 之前已经分析过了Spring的IOC(《零基础带你看Spring源码——IOC控制反转》)与AOP(《从源码入手,一文带你读懂Spring AOP面向切面编程》)的源码,本次...

    array_huang 评论0 收藏0
  • SpringMVC源码分析--ViewResolver(一)

    摘要:概述本章开始进入另一重要的组件,即视图组件,处理视图组件使用两个主要的接口是和。接口的作用是用于处理视图进行渲染。延用之前的介绍流程,本章分两部分进行阐述启动初始化和请求处理。 概述 本章开始进入另一重要的组件,即视图组件,Spring MVC处理视图组件使用两个主要的接口是ViewResolver和View。根据名称可知,ViewResolver即视图解析器,其作用是把逻辑视图名称解...

    pf_miles 评论0 收藏0
  • spring-MVC源码解读(一)

    摘要:处理器是继前端控制器的后端控制器,在的控制下对具体的用户请求进行处理。由于涉及到具体的用户业务请求,所以一般情况需要程序员根据业务需求开发。 1、mcv整体架构和流程 showImg(https://segmentfault.com/img/bV55Qq?w=860&h=406); 用户发送请求至前端控制器 DispatcherServlet DispatcherServlet 收到...

    I_Am 评论0 收藏0

发表评论

0条评论

Dionysus_go

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<