一、前言

既然是浅谈 SpringMVC,那么我们就先从基础说起,本章节主要讲解以下内容:

1、三层结构介绍

2、MVC 设计模式介绍

3、SpringMVC 介绍

4、入门程序的实现

注:介绍方面的内容大多数摘录自互联网,找了一些说法比较严谨、明确的介绍内容进行整理。

二、三层结构介绍

我们的开发架构一般都是基于两种形式,一种是 C/S 架构,也就是客户端/服务器,另一种是 B/S 架构,也就是浏览器服务器。在 JavaEE 开发中,几乎全都是基于 B/S 架构的开发。那么在 B/S 架构中,系统标准的三层架构包括:表现层、业务层、持久层。三层架构在我们的实际开发中使用的非常多,所以我们课程中的案例也都是基于三层架构设计的。

1、表现层

1)也就是我们常说的web 层。它负责接收客户端请求,向客户端响应结果,通常客户端使用http 协议请求web 层,web 需要接收 http 请求,完成 http 响应。

2)表现层包括展示层和控制层:控制层负责接收请求,展示层负责结果的展示。

3)表现层依赖业务层,接收到客户端请求一般会调用业务层进行业务处理,并将处理结果响应给客户端。

4)表现层的设计一般都使用 MVC 模型。(MVC 是表现层的设计模型,和其他层没有关系)

2、业务层

1)也就是我们常说的 service 层。它负责业务逻辑处理,和我们开发项目的需求息息相关。web 层依赖业务层,但是业务层不依赖 web 层。

2)业务层在业务处理时可能会依赖持久层,如果要对数据持久化需要保证事务一致性。(也就是我们说的, 事务应该放到业务层来控制)

3、持久层

1)也就是我们是常说的 dao 层。负责数据持久化,包括数据层即数据库和数据访问层,数据库是对数据进行持久化的载体,数据访问层是业务层和持久层交互的接口,业务层需要通过数据访问层将数据持久化到数据库中。通俗的讲,持久层就是和数据库交互,对数据库表进行增删改查的。

三、MVC 设计模式介绍

MVC 全名是 Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写, 是一种用于设计创建 Web 应用程序表现层的模式。MVC 中每个部分各司其职:

1、Model(模型)

1)模型包含业务模型和数据模型,数据模型用于封装数据,业务模型用于处理业务。

2、View(视图)

1)通常指的就是我们的 jsp 或者 html,作用一般就是展示数据的。

2)通常视图是依据模型数据创建的。

3、Controller(控制器)

1)是应用程序中处理用户交互的部分。作用一般就是处理程序逻辑的。

四、SpringMVC 介绍

1、Spring MVC是什么?

1)SpringMVC 是一种基于 Java 的实现 MVC 设计模型的请求驱动类型的轻量级 Web 框架,属于 SpringFrameWork 的后续产品,已经融合在 Spring Web Flow 里面。Spring 框架提供了构建 Web 应用程序的全功能 MVC 模块。使用 Spring 可插入的 MVC 架构,从而在使用 Spring 进行 WEB 开发时,可以选择使用 Spring 的 SpringMVC 框架或集成其他 MVC 开发框架,如 Struts1(现在一般不用),Struts2 等。

2)它通过一套注解,让一个简单的 Java 类成为处理请求的控制器,而无须实现任何接口。同时它还支持RESTful 编程风格的请求。

3)SpringMVC 和 Struts2 一样,都是为了解决表现层问题的web框架,它们都是基于MCC设计模式的。而这些表现层框架的主要职责就是处理前端HTTP请求。

2、SpringMVC 如何处理请求?

SpringMVC 是基于 MVC 设计模式的,MVC 模式指的就是Model(业务模型)、View(视图)、Controller(控制器)。SpringMVC 处理请求就是通过 MVC 这三种角色来实现的。

不过千万不要把 MVC 设计模式和工程的三层结构混淆,三层结构指的是表现层、业务层、数据持久层。而 MVC 只针对表现层进行设计。

下面根据一张图来看一下 SpringMVC 具体的处理流程:

这张图只是把 SpringMVC 的基本执行流程,详细流程在后续章节中会进行分析。

五、入门程序的实现

1、如何配置前端控制器?

从上面的图可知,我们需要配置一个前端控制器,下面我们会在 web.xml 中进行配置。还有一点就是处理器的开发形式有很多种,有注解方式、实现HttpRequestHandler 接口和实现 Controller 接口,这里我们只讲解注解方式,其他两种方式使用的已经很少了,如果有想要了解的小伙伴,可以自行百度一下。

2、开发步骤

1)创建一个 web 工程,这里一定要注意是 web 工程,和前面的项目有所区别,因为要使用到 web.xml,需要使用 tomcat 进行启动。

2)编写POM文件,添加依赖

<dependencies> <!-- spring ioc组件需要的依赖包 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>5.0.7.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>5.0.7.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.0.7.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-expression</artifactId> <version>5.0.7.RELEASE</version> </dependency> <!-- 基于AspectJ的aop依赖 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>5.0.7.RELEASE</version> </dependency> <dependency> <groupId>aopalliance</groupId> <artifactId>aopalliance</artifactId> <version>1.0</version> </dependency> <!-- spring 事务管理和JDBC依赖包 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>5.0.7.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>5.0.7.RELEASE</version> </dependency> <!-- mysql数据库驱动包 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.35</version> </dependency> <!-- dbcp连接池的依赖包 --> <dependency> <groupId>commons-dbcp</groupId> <artifactId>commons-dbcp</artifactId> <version>1.4</version> </dependency> <!-- mybatis依赖 --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.4.5</version> </dependency> <!-- mybatis和spring的整合依赖 --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>1.3.1</version> </dependency> <!-- SpringMVC 相关包 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>4.3.13.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>4.3.13.RELEASE</version> </dependency> <!-- jstl --> <dependency> <groupId>jstl</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> <!-- servlet --> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> </dependency></dependencies>

这里代码直接给出了,多添加了 SpringMVC 的依赖包,因为会用到 jsp 页面,最后还添加了 jstl 和 servlet-api 的依赖包。

3)配置前端控制器

在web.xml中添加DispatcherServlet的配置。

<?xml version="1.0" encoding="UTF-8"?><web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"     xmlns="http://java.sun.com/xml/ns/javaee"     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"     version="2.5">  <!-- 配置前端控制器 -->  <servlet>    <servlet-name>springmvc</servlet-name>    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>    <!-- 设置spring配置文件路径 -->    <!-- 如果不设置初始化参数,那么DispatcherServlet会读取默认路径下的配置文件,默认配置文件路径:/WEB-INF/springmvc-servlet.xml -->    <init-param>      <param-name>contextConfigLocation</param-name>      <param-value>classpath:springmvc.xml</param-value>    </init-param>    <!-- 指定初始化时机,设置为2,表示Tomcat启动时,DispatcherServlet会跟随着初始化 -->    <!-- 如果不指定初始化时机,DispatcherServlet就会在第一次被请求的时候,才会初始化 -->    <load-on-startup>2</load-on-startup>  </servlet>  <servlet-mapping>    <servlet-name>springmvc</servlet-name>    <!-- 为什么url-pattern配置/*会报错?原因是它拦截了jsp请求,但是却不能处理jsp请求,详见图解 -->    <url-pattern>/</url-pattern>  </servlet-mapping></web-app>

这个地方有几个点需要说明:

(1)web.xml 中配置内容的加载顺序

这个并不属于 SpringMVC 的知识,但是这个地方用到了,就用上面这张图讲解一下。load-on-startup 的配置需要额外注意,配置与不配置的区别很重要,面试经常问道。这里说明一下,它的值需要是大于0的整数,值越小,加载越早,那么为什么我们这里设置了2呢,为什么不设置成1呢?其实设置成1也是完全可以的,但是1是有冲突的,我们可以打开 tomcat 中的 web.xml 看一下就明白了。这是我的个人习惯,这个值已经被占用了,所以就设置为2了。

(2)url-pattern 匹配 URL 详解

在代码中我们可以看到 url-pattern 配置的是 /,这里我们用一张图来看一看为什么这样配置。

这里有一个很经典的问题,为什么 url-pattern 配置 /* 会报错?从图中可以知道 url-pattern 的匹配顺序,如果配置的是 /*,tomcat 本身的配置(*.jsp(就是*.do),/)优先级都小于 /*,就会跳过 tomcat 自身的配置,直接匹配 /*,这样的话,它会接收 jsp 的请求,但是无法处理 jsp 的请求,导致页面访问出错。如果配置为 /,/ 的优先级小于 *.do,jsp 会优先被 tomcat 自身的 *.jsp 处理,这样就没有问题了。

4)创建 springmvc.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"    xmlns:context="http://www.springframework.org/schema/context"    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">  <context:component-scan base-package="top.alanshelby.controller"></context:component-scan></beans>

5)编写处理器

(1)注解方式使用到的注解主要有以下两个:

@Controller 注解:在类上添加该注解,指定该类为一个请求处理器,不需要实现任何接口或者继承任何类。

@RequestMapping 注解:在方法上添加该注解,指定请求的 url 由该方法处理。

处理器的返回值是ModelAndView对象,该对象的具体理解如下:

ModelAndView:方法返回值对象,该对象包含两个功能:一个是将数据存储到 Request 域中,一个是设置响应视图,比如将视图设置为"/WEB-INF/jsp/goodsList.jsp"。

@Controllerpublic class GoodsController {  @RequestMapping(value = "queryGoods")  public ModelAndView queryGoods() {    ModelAndView modelAndView = new ModelAndView();    // 构造演示数据    List<Goods> goodsList = new ArrayList<>();    Goods goods1 = new Goods();    goods1.setName("小米8SE");    goods1.setPrice(1999f);    goods1.setDetail("全面屏智能手机 6GB+64GB 灰色 全网通4G 双卡双待");    Goods goods2 = new Goods();    goods2.setName("Apple iPad");    goods2.setPrice(3359f);    goods2.setDetail("平板电脑 2018年新款9.7英寸(128G WLAN版/A10 芯片/Retina显示屏/Touch ID MRJP2CH/A)金色");    goodsList.add(goods1);    goodsList.add(goods2);    // 设置数据和视图    modelAndView.addObject("goodsList", goodsList);    modelAndView.setViewName("/WEB-INF/jsp/goodsList.jsp");    return modelAndView;  }}

(2)这里直接把实体类和 jsp 页面给出:

Goods.javapublic class Goods {  private String name;  private double price;  private String Detail;  // 省略 setter 和 getter 方法}

goodsList.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %><%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %><%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><body><h2>商品列表</h2></body><hr><div>  <table width="100%" border=1>    <tr>      <td>商品名称</td>      <td>商品价格</td>      <td>商品描述</td>    </tr>    <c:forEach items="${goodsList}" var="item">      <tr>        <td>${item.name}</td>        <td>${item.price}</td>        <td>${item.detail}</td>      </tr>    </c:forEach>  </table></div></html>

六、小结

本章节主要是对 SpringMVC 进行了初步的讲解,让读者能够了解到什么是 MVC 模式、什么事 SpringMVC、SpringMVC 需要如何配置以及它具体的执行流程,目的在于让读者熟悉 SpringMVC,为后面的文章打好基础,后面的章节会更为深入的讲解 SpringMVC。

写在最后:欢迎留言讨论,加关注,持续更新!!!

阿里P7浅谈SpringMVC的更多相关文章

  1. 阿里P7浅谈Java的Spring Bean

    1.简单java 类,实现 Serializable 接口 package com.curtis.bean;import java.io.Serializable;@SuppressWarnings( ...

  2. 浅谈SpringMVC(二)

    一.SpringMVC的拦截器 1.写类implements HandlerInterceptor public class MyMvcInterceptor implements HandlerIn ...

  3. 浅谈SpringMVC(一)

    一.SpringMVC引言 Spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面.Spring 框架提供了构建 Web 应用程序的全功能 MV ...

  4. 浅谈SpringMVC执行过程

    通过深入分析Spring源码,我们知道Spring框架包括大致六大模块, 如Web模块,数据库访问技术模块,面向切面模块,基础设施模块,核心容器模块和模块, 其中,在Spring框架的Web模块中,又 ...

  5. 浅谈SpringMVC

    M--模型(实体vo[视图对象]与页面对面) V--视图(JSP,,velocity,FreeMarker,html,thymeleaf) C--控制器(servlet,if语句控制M数据跳转到V进行 ...

  6. 干货,阿里P8浅谈对java线程池的理解(面试必备)

    线程池的概念 线程池由任务队列和工作线程组成,它可以重用线程来避免线程创建的开销,在任务过多时通过排队避免创建过多线程来减少系统资源消耗和竞争,确保任务有序完成:ThreadPoolExecutor ...

  7. 阿里P7终于讲完了JDK+Spring+mybatis+Dubbo+SpringMvc+Netty源码

    前言 这里普及一下,每个公司都有职别定级系统,阿里也是,技术岗以 P 定级,一般校招 P5, 社招 P6 起.其实阅读源码也是有很多诀窍的,这里分享几点心得: 首先要会用.你要知道这个库是干什么的,掌 ...

  8. 【架构】浅谈web网站架构演变过程

    浅谈web网站架构演变过程   前言 我们以javaweb为例,来搭建一个简单的电商系统,看看这个系统可以如何一步步演变.   该系统具备的功能:   用户模块:用户注册和管理 商品模块:商品展示和管 ...

  9. Android安全开发之浅谈密钥硬编码

    Android安全开发之浅谈密钥硬编码 作者:伊樵.呆狐@阿里聚安全 1 简介 在阿里聚安全的漏洞扫描器中和人工APP安全审计中,经常发现有开发者将密钥硬编码在Java代码.文件中,这样做会引起很大风 ...

随机推荐

  1. 123457123456---熊猫猜谜语02(儿童猜谜语大全)--com.threeObj03.CaiMiYu02

    熊猫猜谜语02(儿童猜谜语大全)--com.threeObj03.CaiMiYu02

  2. mysql stream read.

    Statement stmt = connection.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY) ...

  3. Apache2.4的三种模式

    prefork 多进程模式 一个主进程,负责生成多个子进程,也称工作进程,进程之间独立,每个进程之间只能有一个线程,优点是稳定,缺点是内存占用大,每个进程响应一个用户请求. worker 多线程模式 ...

  4. Efcore迁移

    Efcore迁移 Add-Migration XX:1.根据模型的实际结构对比当前快照,从而生成新迁移文件的Up和Down方法2.根据模型的实际结构修改快照和新迁移文件---------------- ...

  5. 如何抓住ECS的命门,让我们的学习事半功倍

    导读 这是一篇老文写与2019年5月 我们说如何提高我们的学习效率,有人说一本书一般只会讲一个知识点,那我们学习ECS 如何抓住学习的重点,提高学习效率.经过本人一段时间的学习总结,总于找到了一个便捷 ...

  6. Andrew Ng机器学习课程15

    Andrew Ng机器学习课程15 声明:引用请注明出处http://blog.csdn.net/lg1259156776/ 说明:主要介绍了主成分分析,从基本的直观观念出发逐渐推导至公式化的描述,得 ...

  7. Spring 商品分类

    实体商品示例代码 package cn.maxhou.entity; import java.io.Serializable; import java.math.BigDecimal; import ...

  8. windows服务器入门 php的安装

    下载PHP安装包(下载地址: http://windows.php.net/download/ ),本文档以5.3版本为例,选择如下图对应的安装包: 下载完成后进行安装PHP,需要选择Web服务时,选 ...

  9. 在React native 如何写if判断和for循环

    在vue中一般在需要判断时都是通过if语句来实现的,但是在react native中一般则通过三元运算法来实现. 具体代码如下所示. import React from 'react'; import ...

  10. C++编译器、链接器工作原理

    1 几个基本概念 编译:编译器对源文件的编译过程,就是将源文件中的文本形式代码翻译为机器语言形式的目标文件的过程,此过程中会有一系列语法检查.指令优化等,生成目标(OBJ)文件. 编译单元:每一个CP ...