第 11 章 Spring MVC 入门

通过前面章节的学习,大家已经可以掌握 SSM 框架中 Spring 框架和 MyBatis 框架的使用, 并学会了如何将两个框架进行整合。 从本章开始,将讲解 SSM 中的最后一个框架——Spring MVC。

Spring MVC 概述

Spring MVC 是 Spring 提供的一个实现了 Web MVC 设计模式的轻量级 Web 框架。 它与 Struts 2 框架一样,都属于 MVC 框架,但其使用和性能等方面比 Struts 2 更加优异。
Spring MVC 具有如下特点。

  • 是 Spring 框架的一部分,可以方便地利用 Spring 所提供的其他功能。
  • 灵活性强,易于与其他框架集成。
  • 提供了一个前端控制器 DispatcherServlet,使开发人员无须额外开发控制器对象。
  • 可自动绑定用户输入,并能正确的转换数据类型。
  • 内置了常见的校验器,可以校验用户输入。 如果校验不能通过,那么就会重定向到输入表单。
  • 支持国际化。 可以根据用户区域显示多国语言。
  • 支持多种视图技术。 它支持 JSP、 Velocity 和 FreeMarker 等视图技术。
  • 使用基于 XML 的配置文件,在编辑后,不需要重新编译应用程序。

除上述几个优点外, Spring MVC 还有很多其他优点,由于篇幅有限,这里就不一一列举了 。 在接下来的学习中,大家会逐渐地体会到 Spring MVC 的这些优点。

第一个 Spring MVC 应用

了解了什么是 Spring MVC ,以及它的一些优点后,接下来本小节将通过一个简单的入门案例,来演示 Spring MVC 的使用,具体实现步骤如下。

  1. 创建项目,引入 JAR 包
    在 Eclipse 中,创建一个名称为 springmvc01 的 Web 项目,在项目的 lib 目录中添加运行 Spring MVC 程序所需要的 JAR 包,并发布到类路径下,添加后的项目结构如图所示。



    从图中可以看到,项目中添加了 Spring 的 4 个核心 JAR 包、 commons-Iogging 的 JAR 以及两个 Web 相关的 JAR( 可以在 Spring 解压文件夹的 libs 目录中找到),这两个 Web 相关的 JAR 包就是 Spring MVC 框架所需的 JAR 包。 由于在这里我所使用的 Spring 版本是 4.3.6,所以 Spring MVC 也是基于该版本的。

  2. 配置前端控制器
    在 web.xml 中,配置 Spring MVC 的前端控制器 DispatcherServlet,文件如下所示。
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
       xmlns="http://xmlns.jcp.org/xml/ns/javaee" 
       xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" 
       id="WebApp_ID" version="3.1">
       <servlet>
          <!-- 配置前端过滤器  -->
          <servlet-name>springmvc</servlet-name>
          <servlet-class>
              org.springframework.web.servlet.DispatcherServlet
          </servlet-class>
          <!-- 初始化时加载配置文件  -->
          <init-param>
              <param-name>contextConfigLocation</param-name>
              <param-value>classpath:springmvc-config.xml</param-value>
          </init-param>
          <!-- 表示容器在启动时立刻加载Servlet -->
          <load-on-startup>1</load-on-startup>
       </servlet>
       <servlet-mapping>
          <servlet-name>springmvc</servlet-name>
          <url-pattern>/</url-pattern>
       </servlet-mapping>

</web-app>

在文件中,主要对<servlet>和<servlet-mapping>元素进行了配置。 在<servlet>中, 配置了 Spring MVC 的前端控制器 DispatcherServlet ,并通过其子元素<init-param>配置了 Spring MVC 配置文件的位置, <Ioad-on-startup>元素中的 1 表示容器在启动时立即加载这个 Servlet;在<servlet-mapping>中,通过<url-pattern>元素的"/" ,会将所有 URL 拦截,并交由 DispatcherServlet 处理。

  1. 创建 Controller 类
    在 src 目录下,创建一个 com.neuedu.controller 包,并在包中创建控制器类 FirstController, 该类需要实现 Controller 接口,文件如下所示。
package com.neuedu.controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;
/**
* 控制器类
*/
public class FirstController implements Controller {   
  @Override
  public ModelAndView handleRequest(HttpServletRequest arg0, HttpServletResponse arg1) throws Exception {
      //创建ModelAndersonView对象
      ModelAndView mav = new ModelAndView();
      mav.addObject("msg","这是我的第一个Spring MVC 程序!");
      //设计逻辑视图名
      mav.setViewName("/WEB-INF/jsp/frist.jsp");
      return mav;
  }
}

在文件中, handleRequest() 是 Controller 接口的实现方法, FirstController 类会调用该方法来处理请求,并返回一个包含视图名或包含视图名和模型的 ModelAndView 对象。 本案例中,向模型对象中添加了一个名称为 msg 的字符串对象,并设置返回的视图路径为 "/WEB-INF/jsp/first.jsp" ,这样,请求就会被转发到 first.jsp 页面。

  1. 创建 Spring MVC 的配置文件,配置控制器映射信息
    在 src 目录下,创建配置文件 springmvc-config.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"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
   http://www.springframework.org/schema/beans/spring-beans-4.3.xsd">
  <!-- 配置处理器 Handle,映射"/firstController"请求 -->
  <bean name="/firstController" class="com.neuedu.controller.FirstController" />
  <!-- 处理器映射器,将处理器的Handle的name作为url进行查找  -->
  <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping" />
  <!-- 处理器适配器,配置对处理器中 handleRequest()方法的调用 -->
  <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
  <!-- 视图解析器  -->
  <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" />
</beans>

在文件中,首先定义了一个名称为"/firstController" 的 Bean ,该 Bean 会将控制器类 FirstController 映射到" /firstController" 请求中;然后配置了处理器映射器 BeanNameUrlHandlerMapping 和处理器适配器 SimpleControllerHandlerAdapter,其中处理器映射器用于将处理器 Bean 中的的 name (即 url )进行处理器查找,而处理器适配器用于完成对 FirstController 处理器中 handleRequest() 方法的调用 。 最后配置了视图解析器 InternalResourceViewResolver 来解析结果视图,并将结果呈现给用户。
小提示:在老版本的 Spring 中,配置文件内必须要配置处理器映射器、处理器适配器和视图解析器, 但在 Spring 4.0 以后,如果不配置处理器映射器、处理器适配器和视图解析器,也会使用 Spring 内部默认的配置来完成相应的工作,这里显示的配置处理器映射器、处理器适配器和视图解析器是为了让大家能够更加清晰地了解 Spring MVC 的工作流程。

  1. 创建视图 (View) 页面
    在 WEB-INF 目录下,创建一个 JSP 文件夹,并在文件夹中创建一个页面文件 first.jsp ,在该页面中使用 EL 表达式获取 msg 中的信息,文件如下所示。
<%@ page language="java" contentType="text/html; charset=utf-8"
   pageEncoding="utf-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Spring MVC 入门测试</title>
</head>
<body>
  ${msg}
</body>
</html>
  1. 启动顶目,测试应用
    全部文件创建完成后,项目的文件结构如图所示。

    将 springmvc01 项目发布到 Tomcat 中,并启动 Tomcat 服务器。 在浏览器中访问地址 http://localhost:8080/springmvc01/firstController,其显示效果如图 所示。

    从图中可以看到,浏览器中已经显示出了模型对象中的字符串信息,这也就说明第一个 Spring MVC 程序执行成功。
Spring MVC 的工作流程

通过前面章节入门案例的学习,相信大家对 Spring MVC 的使用已经有了一个初步的了解, 但是程序在项目中具体是怎么执行的呢?下面通过一张图来展示 Spring MVC 程序的执行情况, 如图所示。



按照图中所标注的序号, Spring MVC 程序的完整执行流程如下。
( 1 )用户通过浏览器向服务器发送请求,请求会被 Spring MVC 的前端控制器 DispatcherServlet 所拦截。
( 2 ) DispatcherServlet 拦截到请求后,会调用 HandlerMapping 处理器映射器。
( 3 )处理器映射器根据请求 URL 找到具体的处理器,生成处理器对象及处理器拦截器(如果有则生成)一并返回给 DispatcherServlet。
( 4 ) DispatcherServlet 会通过返回信息选择合适的 HandlerAdapter (处理器适配器)。
( 5 ) HandlerAdapter 会调用并执行 Handler (处理器),这里的处理器指的就是程序中编写的 Controller 类,也被称之为后端控制器。
( 6 ) Controller 执行完成后,会返回一个 ModelAndView 对象,该对象中会包含视图名或包含模型和视图名。
( 7 ) HandlerAdapter 将 ModelAndView 对象返回给 DispatcherServlet。
( 8 ) DispatcherServlet 会根据 ModelAndView 对象选择一个合适的 ViewReslover (视图解 析器)。
( 9 ) ViewReslover 解析后,会向 DispatcherServlet 中返回具体的 View (视图)。
( 10 ) DispatcherServlet 对 View 进行渲染(即将模型数据填充至视图中)。
( 11 )视图渲染结果会返回给客户端浏览器显示。
在上述执行过程中, DispatcherServlet、 HandlerMapping、 HandlerAdapter 和 ViewResolver 对象的工作是在框架内部执行的,开发人员并不需要关心这些对象内部的实现过程,只需要配置前端控制器( DispatcherServlet ),完成 Controller 中的业务处理,并在视图中 (View) 中展示相应信息即可。

本章小结

本章首先对 Spring MVC 框架进行了简单的介绍,然后讲解了一个 Spring MVC 入门程序的编写,最后通过入门案例对 Spring MVC 的工作流程进行了详细讲解。 通过本章的学习,大家能够了解什么是 Spring MVC 以及 Spring MVC 的优点,掌握 Spring MVC 入门程序的编写,并能够熟悉 Spring MVC 框架的工作流程。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,921评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,635评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,393评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,836评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,833评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,685评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,043评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,694评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,671评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,670评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,779评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,424评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,027评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,984评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,214评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,108评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,517评论 2 343