专栏首页CodeSheep的技术分享从SpringBoot到SpringMVC
原创

从SpringBoot到SpringMVC

V A I O

概述

用久了SpringBoot,深受其约定大于配置的便利性毒害之后,我想回归到SpringMVC时代,看看SpringMVC开发模式中用户是如何参与的。本文就来体验一下SpringMVC时代开发的流程。


SpringMVC架构模式

SpringMVC请求处理流程

一个典型的SpringMVC请求流程如图所示,详细分为12个步骤:

  1. 用户发起请求,由前端控制器DispatcherServlet处理
  2. 前端控制器通过处理器映射器查找hander,可以根据XML或者注解去找
  3. 处理器映射器返回执行链
  4. 前端控制器请求处理器适配器来执行hander
  5. 处理器适配器来执行handler
  6. 处理业务完成后,会给处理器适配器返回ModeAndView对象,其中有视图名称,模型数据
  7. 处理器适配器将视图名称和模型数据返回到前端控制器
  8. 前端控制器通过视图解析器来对视图进行解析
  9. 视图解析器返回真正的视图给前端控制器
  10. 前端控制器通过返回的视图和数据进行渲染
  11. 返回渲染完成的视图
  12. 将最终的视图返回给用户,产生响应

整个过程清晰明了,下面我们将结合实际实验来理解这整个过程。


SpringMVC项目搭建

实验环境如下:

  • IntelliJ IDEA 2018.1 (Ultimate Edition)
  • SpringMVC 4.3.9.RELEASE
  • Maven 3.3.9

这里我是用IDEA来搭建的基于Maven的SpringMVC项目,搭建过程不再赘述,各种点击并且下一步,最终创建好的项目架构如下:

基于Maven的SpringMVC项目

添加前端控制器配置

使用了SpringMVC,则所有的请求都应该交由SpingMVC来管理,即要将所有符合条件的请求拦截到SpringMVC的专有Servlet上。

为此我们需要在 web.xml 中添加SpringMVC的前端控制器DispatcherServlet:

    <!--springmvc前端控制器-->
    <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:mvc-dispatcher.xml</param-value>
        </init-param>
    </servlet>

    <servlet-mapping>
        <servlet-name>mvc-dispatcher</servlet-name>
        <url-pattern>*.action</url-pattern>
    </servlet-mapping>

该配置说明所有符合.action的url,都交由mvc-dispatcher这个Servlet来进行处理


编写SpringMVC核心XML配置文件

从上一步的配置可以看到,我们定义的mvc-dispatcher Servlet依赖于配置文件 mvc-dispatcher.xml,在本步骤中我们需要在其中添加三个方面的配置

  • 0x01. 添加处理器映射器
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping" />

SpringMVC的处理器映射器有多种,这里的使用的BeanNameUrlHandlerMapping其映射规则是将bean的name作为url进行处理

  • 0x02. 添加处理器适配器
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter" />

SpringMVC的处理器适配器也有多种,这里的使用的SimpleControllerHandlerAdapter是Controller实现类的适配器类,其本质是执行Controller中的handleRequest方法。

  • 0x03. 添加试图解析器
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" />

这里配置了InternalResourceViewResolver视图解析器后,其会根据controller方法执行之后返回的ModelAndView中的视图的具体位置,来加载对应的界面并绑定数据


编写控制器

这里模拟的是一个打印学生名单的Service,我们编写的控制器需要将查询到的学生名单数据通过ModelAndView渲染到指定的JSP页面中

public class TestController implements Controller {

    private StudentService studentService = new StudentService();

    @Override
    public ModelAndView handleRequest( HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
        List<Student> studentList = studentService.queryStudents();
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.addObject("studentList",studentList);
        modelAndView.setViewName("/WEB-INF/views/studentList.jsp");
        return modelAndView;
    }
}

class StudentService {
    public List<Student> queryStudents() {
        List<Student> studentList = new ArrayList<Student>();

        Student hansonwang = new Student();
        hansonwang.setName("hansonwang99");
        hansonwang.setID("123456");

        Student codesheep = new Student();
        codesheep.setName("codesheep");
        codesheep.setID("654321");

        studentList.add(hansonwang);
        studentList.add(codesheep);

        return studentList;
    }
}

编写视图文件

这里的视图文件是一个jsp文件,路径为:/WEB-INF/views/studentList.jsp

<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>

<html>
<head>
    <title>学生名单</title>
</head>
<body>
    <h3>学生列表</h3>
    <table width="300px;" border=1>
        <tr>
            <td>姓名</td>
            <td>学号</td>
        </tr>
        <c:forEach items="${studentList}" var="student" >
            <tr>
                <td>${student.name}</td>
                <td>${student.ID}</td>
            </tr>
        </c:forEach>
    </table>
</body>
</html>

结合本步骤和上一步骤,视图和控制器都已编写完成,由于我们之前配置的处理器映射器为:BeanNameUrlHandlerMapping,因此接下来我们还需要在mvc-dispatcher.xml文件中配置一个可被url映射的controller的bean,供处理器映射器BeanNameUrlHandlerMapping查找:

<bean name="/test.action" class="cn.codesheep.controller.TestController" />

实验测试

启动Tomcat服务器,然后浏览器输入:

http://localhost:8080/test.action
实验结果

数据渲染OK。

备注:当然本文所使用的全是非注解的配置方法,即需要在XML中进行配置并且需要遵循各种实现原则。而更加通用、主流的基于注解的配置方法将在后续文章中详述。


后记

作者更多的SpringBt实践文章在此:


如果有兴趣,也可以抽点时间看看作者一些关于容器化、微服务化方面的文章:


作者更多 务实、能看懂、可复现的 原创文章尽在公众号 CodeSheep,欢迎订阅哦 ⬇️⬇️⬇️

CodeSheep

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 从 SpringBoot 到 SpringMVC

    用久了 SpringBoot,深受其约定大于配置的便利性毒害之后,我想回归到 SpringMVC 时代,看看 SpringMVC 开发模式中用户是如何参与的。本...

    砸漏
  • 如何理解spring大礼包——spring、springMvc、springBoot和springCloud

    瑞新
  • springboot和springmvc

    springboot是一个用于快速设置应用程序的实用工具,它提供了开箱即用的配置来构建基于Spring的应用程序,对于初学者来说,这带来了许多困扰,初学...

    叔牙
  • SpringBoot+SpringMVC+MyBatis快速整合搭建

    SpringBoot是基于Spring4.0设计的,不仅继承了Spring框架原有的优秀特性,而且还通过简化配置来进一步简化了Spring应用的整个搭建和开发过...

    IT大咖说
  • 纯手写SpringMVC到SpringBoot框架项目实战

    Spring Boot其设计目的是用来简化新Spring应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置。

    用户5224393
  • 【SpringBoot源码解析】第四章:SpringBoot是如何自动装配SpringMvc的

    在上一章中,我们介绍了SpringBoot是如何启动一个内置tomcat的。我们知道我们在SpringBoot项目里面是可以直接使用诸如@RequestMapp...

    诺浅
  • Spring&SpringMVC&SpringBoot

    Spring框架就像一个家族,在Spring的基础上产生了很多产品,例如:SpringBoot、SpringSecurity、SpringJPA、SpringD...

    TrueDei
  • Spring、SpringMVC和SpringBoot看这一篇就够了!

    Spring是一个开源容器框架,可以接管web层,业务层,dao层,持久层的组件,并且可以配置各种bean,和维护bean与bean之间的关系。其核心就是控制反...

    刘文正
  • 初识SpringBoot

    在日常开发中,我们通常会选择SpringMVC + Maven的方式去构建一个web项目,需要配置各种xml文件非常耗时,大概的构建步骤如下:

    会说话的丶猫

扫码关注云+社区

领取腾讯云代金券