一、前言

既然是浅谈 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. php关于文件上传的两个配置项说明

    ; Maximum allowed size for uploaded files.; http://php.net/upload-max-filesizeupload_max_filesize = ...

  2. 【ARM-Linux开发】Rico Board DIY系列实验教程 Day 2——搭建Boa服务器

    一:BOA WebServer简介 BOA WebServer是一款单任务的HTTP服务器,与其他网页服务器不同之处,是当有连接请求到来是,它既不是为每个连接都单独创建进程,也不是采用复制自身进程处理 ...

  3. 关于VS2010工程各种路径注意事项汇总

    关于VS2010工程各种路径注意事项汇总 声明:引用请注明出处http://blog.csdn.net/lg1259156776/ 说明:前段时间调试,利用cmake生成的vs2010工程文件,虽然该 ...

  4. vue-cli2和vue-cli3同时存在

    https://blog.csdn.net/Jioho_chen/article/details/90455778 win下 vue-cli2 和 vue-cli3 并存,一起使用开局一张图,内容慢慢 ...

  5. HTML让字体闪动和滚动显示

    存粹的HTML让字体闪动显示: <html> <head> <title>TEST</title> <style type="text/ ...

  6. php 将图片文件转成base64编码的方法

    php 将图片文件转成base64编码的方法<pre><?php /** 文件转base64输出 * @param String $file 文件路径 * @return Strin ...

  7. Markdonw 详细入门教程

    1. Markdown语法快速入门手册 2 Markdown概述 2.1 Markdown宗旨 2.2 Markdown兼容HTML 2.3 Markdown特殊字符自动转换 2.4 Markdown ...

  8. STM32的I2C通讯过程

    使用I2C外设通讯时,在通讯的不同阶段它会对“状态寄存器(SR1 及SR2)”的不同数据位写入参数,通过读取这些寄存器标志来了解通讯状态. 1.主发送器 可使用STM32标准库函数来直接检测这些事件的 ...

  9. Gossip协议

    Gossip数据传播协议: Fabric通过将工作负载划分到事务执行(背书和提交)对等节点和事务排序节点,优化了区块链网络性能.安全性和可伸缩性.这种网络操作的解耦需要一个安全.可靠和可伸缩的数据传播 ...

  10. nginx 设置开机启动

    设置nginx开机启动chkconfig --add /etc/init.d/nginx chkconfig nginx on