1. Spring MVC介绍

提到MVC,参与过Web应用程序开发的同学都很熟悉,它是展现层(也可以理解成直接展现给用户的那一层)开发的一种架构模式,M全称是Model,指的是数据模型,V全称是View,指的是视图页面,如JSP、Thymeleaf等,C全称是Controller,指的是控制器,用来处理用户在客户端(浏览器)发起的请求。

Spring MVC就是基于MVC模式实现,能够帮你构建像Spring框架那样灵活和松耦合的Web应用程序。

也就是说,Spring MVC是基于Spring的,它主要用来开发Web应用程序。

2. Spring MVC请求流程

在Web应用程序中,请求是必不可少的,每次请求由用户(客户端)发起,到用户(客户端)接收到响应结束,下图展示了一个请求在Spring MVC中所经历的每个流程:

接下来我们对图中的每个流程做下讲解:

  1. 请求离开浏览器时(图中的①),会带有用户所请求内容的信息,比如请求的URL和提交的表单信息。
  2. 然后进入到请求的第一站,即Spring的DispatcherServlet,它的任务是将请求发送给Spring MVC控制器。
  3. 因为在应用程序中会有多个控制器,因此DispatcherServlet会查询一个或多个处理器映射(handler mapping),处理器映射会根据请求所携带的URL来确定应该将请求发送给哪个控制器(图中的②)。
  4. 确定好控制器后,DispatcherServlet会将请求发送给确定好的控制器,然后等待控制器处理用户提交的信息,不过一般情况下,控制器本身几乎不处理工作,而是将业务逻辑委托给一个或多个服务对象进行处理(图中的③)。
  5. 控制器完成业务逻辑处理后,通常会产生一些模型(Model)信息,这些信息需要返回给用户并在浏览器上显示,为了更友好的展示这些信息,比如以Html形式展示,我们需要将信息发送给一个视图(View),比如JSP、Thymeleaf。
  6. 控制器所做的最后一件事就是将模型数据打包,并且标示出用于渲染输出的视图名,它会将请求连同模型和视图名发送回DispatcherServlet(图中的④),不过控制器只会返回一个视图的逻辑名称,而不是返回具体的某个特定视图,这个逻辑名称将会用来查找产生结果的真正视图。DispatcherServlet会使用视图解析器(view resolver)来将逻辑视图名匹配为某个特定视图(图中的⑤),比如JSP或者Thymeleaf。
  7. 请求的最后一站是视图的实现(图中的⑥),在这里视图将使用模型数据渲染输出,这个输出会通过响应对象传递给用户/客户端(图中的⑦)。

了解了Spring MVC的请求流程后,我们来接着了解下如何搭建和配置Spring MVC项目。

3. 搭建Spring MVC项目

我们仍然延用之前博客中新建的spring-action项目,有兴趣的同学可以看下本系列的前11篇博客或者直接下载源码:https://github.com/zwwhnly/spring-action.git

3.1 添加依赖

要想使用Spring MVC,首先我们需要在pom.xml中添加如下依赖:

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.3.18.RELEASE</version>
</dependency> <!-- 其他Web依赖 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>

因为后面要将项目部署到Tomcat,所以我们在pom.xml中配置下打包方式为war包:

<packaging>war</packaging>

<build>
<plugins>
<!--其他配置-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.3</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
</plugins>
</build>

3.2 新建演示页面

在src/main/resources下新建views目录,然后在此目录下新建index.jsp页面如下所示:

<%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="UTF-8" %>
<html>
<head>
<title>Spring MVC</title>
</head>
<body>
<pre>
Welcome to Spring MVC world
</pre>
</body>
</html>

这里可能存在的问题是,右键新建JSP文件时,没有JSP文件模板,就像下面这样:

解决方案如下所示:

依次点击File--Project Structure,打开Project Structure对话框,左侧选中Modules,然后点击+号,选择Web

此时再次右键新增JSP文件,就会看到JSP文件模板:

此时项目根目录会生成1个web文件夹,可以将其删除。

3.3 Spring MVC配置

新建配置类MyMvcConfig如下所示:

package chapter05.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView; /**
* Spring MVC配置
*/
@Configuration
@EnableWebMvc
@ComponentScan("chapter05")
public class MyMvcConfig {
/**
* 视图解析器配置
*
* @return
*/
@Bean
public InternalResourceViewResolver viewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver(); viewResolver.setPrefix("/WEB-INF/classes/views/");
viewResolver.setSuffix(".jsp");
viewResolver.setViewClass(JstlView.class); return viewResolver;
}
}

注意事项:

1)该配置类使用了@EnableWebMvc注解来启用Spring MVC,它会开启一些默认配置。

2)该配置类配置了视图解析器,这里我们配置的是JSP的视图解析器。

视图解析器中,我们设置了前缀和后缀,如果控制器中返回的逻辑视图名称是index,实际渲染时找的视图就是/WEB-INF/classes/views/index.jsp,为什么设置的前缀是/WEB-INF/classes/views/而不是/src/main/resources/views/呢,那是因为项目编译完运行时的目录是/WEB-INF/classes/views/。

如果编译完成该目录下没有jsp文件,则需要在pom.xml中添加如下配置:

<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.jsp</include>
<include>**/*.js</include>
</includes>
</resource>
</resources>
</build>

3.4 Web配置

新建Web配置类WebInitializer如下所示:

package chapter05.config;

import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet; import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration.Dynamic; public class WebInitializer implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
context.register(MyMvcConfig.class);
context.setServletContext(servletContext); Dynamic servlet = servletContext.addServlet("dispatcher", new DispatcherServlet(context));
servlet.addMapping("/");
servlet.setLoadOnStartup(1);
}
}

这里重点要关注的是,该类实现了接口WebApplicationInitializer并重写了onStartup()方法,WebApplicationInitializer类是Spring提供用来配置Servlet 3.0+版本配置的接口,从而可以替代掉web.xml。

3.5 新建控制器

新建控制器HelloController如下所示:

package chapter05.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping; @Controller
public class HelloController {
@RequestMapping("/index")
public String hello() {
// 这里返回的逻辑视图名
return "index";
}
}

上面代码中的@Controller注解声明这是1个控制器,@RequestMapping("/index")用来配置URL映射,现在问题来了,我们如何查看代码的运行效果呢?

这就涉及到了项目打包和项目部署,我们继续往下看。

4. 项目部署到Tomcat中

4.1 打包(war包)

因为我们的项目是通过Maven管理的,在pom.xml中也配置了打包方式为war包和打包插件,所以我们可以在IDEA的右侧找到Maven资源管理器,然后如下图所示,点击clean:

然后再点击package:

最后生成的war包如下所示:

这就是我们要部署到Tomcat中的war包。

4.2 Tomcat安装及部署

既然要部署到Tomcat中,那么就有2个问题需要解答:

  1. 什么是Tomcat?
  2. Tomcat如何安装?

先回答第1个问题,Tomcat是一个免费的开放源代码的轻量级的Web应用服务器,如果你接触过.NET的Web开发,它就类似于IIS。

再回答第2个问题,可以参考如下步骤安装Tomcat。

打开Tomcat官网,找到你要下载的Tomcat版本,我这里选择的是Tomcat 8.5.45 Released版本:

然后选择合适的版本下载,因为我的开发机器是Windows 64位操作系统,所以我选择的是如下所示的版本:

下载完成后,将其解压到你喜欢的目录,我解压到的目录是E:\Tools\apache-tomcat-8.5.45-windows-x64\apache-tomcat-8.5.45,解压完成后长如下这样:

其中webapps就是网站要部署的目录。

安装完成后,考虑的问题就是如何启动Tomcat?

第1种方法是双击bin目录下的tomcat8.exe:

然后在浏览器输入地址http://localhost:8080/,看到如下界面,代表Tomcat安装部署成功。

使用这种方法的缺点就是,如果把tomcat8.exe打开的窗口关闭了,Tomcat也就关闭了,非常不方便,因此建议使用第2种方法,将Tomcat安装成一个后台服务,让其在后台运行,操作方法如下所示:

依次打开计算机--属性--高级系统设置--高级--环境变量,新增系统变量:

变量名:CATALINA_HOME

变量值:E:\Tools\apache-tomcat-8.5.45-windows-x64\apache-tomcat-8.5.45(你将Tomcat解压的目录)

然后编辑系统变量Path,在其最后添加如下内容:

;%CATALINA_HOME%\lib;%CATALINA_HOME%\bin

然后以管理员身份打开cmd窗口,切换到Tomcat的bin目录,执行命令:service.bat install。

然后打开Windows的服务列表,会看到一个Tomcat8的服务:

将服务修改成自动启动并启动该服务即可在后台一直运行Tomcat服务器。

如果你好奇新建的系统变量为什么必须是CATALINA_HOME,那么可以用记事本打开bin目录下的service.bat,看到如下内容你就明白了:

从上图也可以看出,运行Tomcat需要依赖环境变量JAVA_HOME(配置JAVA SDK路径),不过我之前已经配置过了,如下所示:

4.3 将war包部署到Tomcat中

将之前打包好的spring-action-1.0-SNAPSHOT.war复制到Tomcat的webapps目录:

因为我们的Tomcat服务器设置成了后台运行,过一会该目录就会生成1个和war包名相同的spring-action-1.0-SNAPSHOT文件夹,目录结构如下所示:

我们的代码和JSP视图文件都在WEB-INF目录下的classes文件夹下:

在浏览器中输入地址http://localhost:8080/spring-action-1.0-SNAPSHOT/index,页面展示如下所示:

5. 源码及参考

源码地址:https://github.com/zwwhnly/spring-action.git,欢迎下载。

Craig Walls 《Spring实战(第4版)》

汪云飞《Java EE开发的颠覆者:Spring Boot实战》

【IntelliJ IDEA】使用idea解决新建jsp文件而找不到jsp文件模版的新建选项

Tomcat安装及配置教程

Tomcat安装及后台运行的方法

原创不易,如果觉得文章能学到东西的话,欢迎点个赞、评个论、关个注,这是我坚持写作的最大动力。

如果有兴趣,欢迎添加我的微信:zwwhnly,等你来聊技术、职场、工作等话题(PS:我是一名奋斗在上海的程序员)。

Spring入门(十二):Spring MVC使用讲解的更多相关文章

  1. Spring入门(十):Spring AOP使用讲解

    1. 什么是AOP? AOP是Aspect Oriented Programming的缩写,意思是:面向切面编程,它是通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术. 可以认为AOP是 ...

  2. Spring学习(十二)-----Spring @PostConstruct和@PreDestroy实例

    实现 初始化方法和销毁方法3种方式: 实现标识接口 InitializingBean,DisposableBean(不推荐使用,耦合性太高) 设置bean属性 Init-method destroy- ...

  3. Spring学习(十二)-----Spring Bean init-method 和 destroy-method实例

    实现 初始化方法和销毁方法3种方式: 实现标识接口 InitializingBean,DisposableBean(不推荐使用,耦合性太高) 设置bean属性 Init-method destroy- ...

  4. Spring入门(十四):Spring MVC控制器的2种测试方法

    作为一名研发人员,不管你愿不愿意对自己的代码进行测试,都得承认测试对于研发质量保证的重要性,这也就是为什么每个公司的技术部都需要质量控制部的原因,因为越早的发现代码的bug,成本越低,比如说,Dev环 ...

  5. Spring Boot(十二):spring boot如何测试打包部署

    Spring Boot(十二):spring boot如何测试打包部署 一.开发阶段 1,单元测试 在开发阶段的时候最重要的是单元测试了,springboot对单元测试的支持已经很完善了. (1)在p ...

  6. [Spring框架]Spring AOP基础入门总结二:Spring基于AspectJ的AOP的开发.

    前言: 在上一篇中: [Spring框架]Spring AOP基础入门总结一. 中 我们已经知道了一个Spring AOP程序是如何开发的, 在这里呢我们将基于AspectJ来进行AOP 的总结和学习 ...

  7. Spring Boot2 系列教程(三十二)Spring Boot 整合 Shiro

    在 Spring Boot 中做权限管理,一般来说,主流的方案是 Spring Security ,但是,仅仅从技术角度来说,也可以使用 Shiro. 今天松哥就来和大家聊聊 Spring Boot ...

  8. Android入门(十二)SQLite事务、升级数据库

    原文链接:http://www.orlion.ga/610/ 一.事务 SQLite支持事务,看一下Android如何使用事务:比如 Book表中的数据都已经很老了,现在准备全部废弃掉替换成新数据,可 ...

  9. Spring学习十四----------Spring AOP实例

    © 版权声明:本文为博主原创文章,转载请注明出处 实例 1.项目结构 2.pom.xml <project xmlns="http://maven.apache.org/POM/4.0 ...

随机推荐

  1. PHP 数组转字符串后仍保留数组格式

    写此方法的目的是,我想把一个PHP数组配置文件读进程序,添加些配置,然后在写入文件: var_export 方法会把原来的配置打乱(比如数组序号我没有加,他自动给我加上 0,1,2,3...),而且格 ...

  2. exlipse php 插件安装地址

    以前的exlipse PHP插件老是有问题,下面这个地址可以使用. http://www.phpsrc.org/eclipse/pti/

  3. Streaming-大数据的未来

    分享一篇关于实时流式计算的经典文章,这篇文章名为Streaming 101: The world beyond batch 那么流计算如何超越批处理呢? 从这几个方面说明:实时流计算系统,数据处理模式 ...

  4. tab栏切换制作

    tab栏切换制作 先上图 要求1:默认状态,第一个选项卡被选中,展示第一个选项卡的内容 策略:第一个选项卡默认有被选中的样式,第一个选项卡对应的display: block,其他的dispaly设为n ...

  5. JavaScript数组方法大全(第二篇)

    数组方法大全(第二篇) 注意:如有错误欢迎指出,如有雷同纯属巧合,本博客参考书籍JavaScript权威指南,有兴趣的小伙伴可以去翻阅一下哦 forEach()方法 遍历数组,里面可以传递一个方法 v ...

  6. Python中模块与包的导入(朴实易懂版的总结)

    这几天,被python包与模块的导入问题,折磨的不行,以前想的很简单,其实不然,经查资料研究,特总结如下: 基本注意点 模块:一般指一个py文件:包:含有许多py文件的文件夹,含有 或不含有(Pyth ...

  7. .Net使用HttpClient以multipart/form-data形式post上传文件及其相关参数

    前言: 本次要讲的是使用.Net HttpClient拼接multipark/form-data形式post上传文件和相关参数,并接收到上传文件成功后返回过来的结果(图片地址,和是否成功).可能有很多 ...

  8. Markdown表格宽度调整

    Markdown 表格默认宽度是根据内容来的,如果某一列内容很长的话会将其他列的宽度占用导致显示样式很丑.我们可以在表格前增加 CSS 样式来限制列的宽度: <style> table t ...

  9. 前端优化---回流 (reflow)与 重绘(repaint)

    回流(reflow):指的是网络浏览器为了重新渲染部分或全部的文档而重新计算文档中元素的位置和几何结构的过程. 页面上节点是以树的形式展现的,我们通过js将页面上的一个节点删除,此时为了不让剩下的节点 ...

  10. Python -二叉树 创建与遍历算法(很详细)

    树表示由边连接的节点.它是一个非线性的数据结构.它具有以下特性. 一个节点被标记为根节点. 除根节点之外的每个节点都与一个父节点关联. 每个节点可以有一个arbiatry编号的chid节点. 我们使用 ...