SpringMVC(一)【入门】

前言

        学完了大数据基本组件,SpringMVC 也得了解了解,为的是之后 SpringBoot 能够快速掌握。SpringMVC 可能在大数据工作中用的不多,但是 SSM 毕竟是现在就业必知必会的东西了。SpringBoot 在数仓开发可能会经常用到,所以不废话学吧。

1、SpringMVC 概述

1.1、请求响应模式演进过程

1.1.1、三层架构

  • web:页面数据的收集以及产生页面
  • service:业务处理
  • dao:数据持久化

弊端:一个 Servlet 只能一个处理请求。

1.1.2、MVC 模式

        浏览器将请求发送给控制器,控制器调用 Service 层,再由 Service 层调用 dao 层得到数据,将得到的数据组织成数据模型(封装成对象),然后将页面和数据模型封装到一起返回给浏览器。这样,一个 Servlet 就可以处理多个请求了。

        MVC 模式下的 view 一般用的是 jsp,但是现在我们一般都用的是 HTML、CSS、E        lementUI、Vue 这些技术:

1.13、异步调用

        异步调用模式下,我们不再需要将 jsp 和 model 共同返回给浏览器展示了,而是页面和 model 分开,页面用 html、vue 这些前端技术,model 需要将它封装成 json 对象返回给我们的前端(因为 java 对象不能直接返回给页面):

这样,我们的前端页面就可以从 json 中把数据抽取出来,然后组织成页面展示到浏览器上面。

异步调用下 SpringMVC 的任务
  • Controller 层的开发
  • 数据转为 json 格式返回给前端

2、SpringMVC 入门案例

2.1、入门案例

使用 Servlet 开发 web 程序的过程:

  1. 创建 web 工程
  2. 设置 tomcat 服务器
  3. 导入依赖(Servlet)
  4. 定义处理请求的功能类(UserServlet)
  5. 配置请求映射关系

使用 SpringMVC 开发 web 程序的过程:

  1. 创建 web 工程
  2. 设置 tomcat 服务器
  3. 导入依赖(SpringMVC + Servlet)
  4. 定义处理请求的功能类(UserController
  5. 配置请求映射关系
  6. 将 SpringMVC 设定加载到 Tomcat 容器中

0、配置环境

1、导入依赖

<build>
    <plugins>
      <plugin>
        <groupId>org.apache.tomcat.maven</groupId>
        <artifactId>tomcat7-maven-plugin</artifactId>
        <version>2.2</version>
        <configuration>
          <port>85</port>
          <path>/</path>
          <ignorePackaging>true</ignorePackaging>
        </configuration>
      </plugin>
    </plugins>
  </build>

  <dependencies>
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>3.1.0</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>5.2.0.RELEASE</version>
    </dependency>
  </dependencies>

2、初始化SpringMVC环境

@Configuration
public class SpringMvcConfig {
}

3、创建 SpringMVC 控制器类(等同于 Servlet 功能)

@Controller
public class UserController {

    @RequestMapping("/save")
    public void save(){
        System.out.println("user save ...");
    }

}

4、设定SpringMVC加载对应的Bean

@Configuration
@ComponentScan("com.lyh.controller") // 扫描
public class SpringMvcConfig {

}

5、初始化 Servlet 容器,加载SpringMVC 环境,并设置 SpringMVC 请求拦截的路径

/**
 * Servlet 容器配置类
 */
public class ServletContainersInitConfig extends AbstractDispatcherServletInitializer {

    /**
     * 加载SpringMVC容器对象
     * @return
     */
    protected WebApplicationContext createServletApplicationContext() {
        AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
        ctx.register(SpringMvcConfig.class);
        return ctx;
    }

    /**
     * 请求由谁来处理?tomcat/springmvc
     * @return
     */
    protected String[] getServletMappings(){
        return new String[]{"/"};  // 所有请求都由 springmvc 来处理
    }

    /**
     * 加载 Spring 的配置对应的容器对象
     * @return
     */
    protected WebApplicationContext createRootApplicationContext() {
        return null;
    }
}

6、报错1

访问 localhost:85/save 报错:

7、设置请求返回值为 json 信息 并添加注解@ResponseBody 代表返回内容就是响应内容

8、重新请求  localhost:85/save 

2.2、注解&配置类说明

2.2.1、注解

名称类型位置作用参数
@Controller类注解控制器类上方设置SpringMVC的核心控制器Bean无参
@RequestMapping方法注解控制器方法上面设置当前控制器方法请求访问路径@RequestMapping("/save") 访问的时候就访问 localhost:85/save
@ResponseBody方法注解控制器方法上面设置当前控制器方法的返回值就是响应内容无参

 2.2.2、AbstractDispatcherServletInitializer

AbstractDispatcherServletInitializer 是 SpringMVC 提供的快速初始化 Web3.0 容器的抽象类,它提供了三个接口抽象方法供用户实现:

1)createServletApplicationContext

作用:加载 SpringMVC 容器,一旦 tomcat 启动,就会把这个容器加载到 tomcat 容器中。

2)getServletMappings

作用:设定 SpringMVC 对应的请求路径,也就是哪些请求由 SpringMVC 管,哪些由 tomcat 管。返回 "/" 代表拦截所有请求交给 SpringMVC 处理。

 3)createRootApplicationContext

作用:加载除了 SpringMVC 之外的所有容器的内容(Bean)

这里我们没有其它容器,所以直接返回 null。 

2.3、总结

对于一次性工作,我们以后做项目直接 CV 大法然后改一改就好了。我们真正做的最多的还是多次工作:定义控制器、定义控制器中的方法等。

3、SpringMVC 工作流程分析

工作流程主要分为两部分:

  1. 启动服务器
  2. 发送一次请求

3.1、服务器初始化过程

在 Web3.0 的规范中,我们不再需要 web.xml 来配置,而是通过一个配置类(继承 AbstractDispatcherServletInitializer 抽象类)来完成。

3.2、单次请求工作流程

4、Bean 加载控制

4.1、Controller 加载控制与业务 Bean 加载控制

现在我们的项目结构是这样的: 

  • config目录存入的是配置类,我们之后的配置类会有:

    • ServletContainersInitConfig

    • SpringConfig

    • SpringMvcConfig

    • JdbcConfig

    • MybatisConfig

  • controller目录存放的是SpringMVC的controller类

  • service目录存放的是service接口和实现类

  • dao目录存放的是dao/Mapper接口

4.1.1、SpringMVC 相关 Bean 加载控制

  • SpringMVC 加载的 Bean 都放在 com.lyh.controller 包下

        controller 包下的所有 Bean 会被 SpringMVC 来加载,而其它包(dao、service等)下的 Bean 都应该由 Spring 来加载,但是如何控制 Spring 不去加载 SpringMVC 中的 Bean ? 

4.1.2、Spring 相关 Bean 加载控制

  • 方式一:Spring 加载的 Bean 设定扫描范围为 com.lyh,排除掉 controller 包内的 Bean
  • 方式二:Spring 加载的 Bean 设定扫描范围为精准范围,比如 service、dao包等
  • 方式三:不区分 Spring 和 SpringMVC 的环境,都加载到同一个环境中。

方式一:只加载 Spring 管理的 Bean: 

@Configuration
@ComponentScan({"com.lyh.service","com.lyh.dao"})
public class SpringConfig {

}

方式二:按照注解进行过滤,过滤掉由 SpringMVC 管理的包下的 Bean:

@Configuration
@ComponentScan(value = "com.lyh",
        excludeFilters = @ComponentScan.Filter(
                type = FilterType.ANNOTATION,
                classes = Controller.class
        ))
public class SpringConfig {

}

测试

public class App {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
        // 如果Controller类被Spring注册了,会输出对象地址
        // 如果没有被注册,那么会报错
        System.out.println(ctx.getBean(UserController.class));
    }
}

 注意:在测试时,SpringMvcConfig 的注解 Configuration 需要去掉,因为 SpringConfig 中我们设置 Spring 会扫描所有 com.lyh 目录下的目录(除了 exclude 之外的),但是 Spring 会把所有带有 @Configuration 注解的类加载一遍,而 SpringMvcConfig 上面除了 @Configuration 之外还有一个注解 @ComponentScan 用来扫描 controller 包,所以 Spring 又会把 controller 目录下的 Bean 加载一遍。

        所以我们可以把这两个带有 @Configuration 注解的配置类放到 com.lyh 包外边,防止被 Spring 加载。

到这里,我们需要把由 Spring 加载的环境配置放到 ServletContainersInitConfig 中:

这样,当服务器启动后,tomcat 容器中就不只有 SpringMVC 的容器了,还有 Spring 的容器。

4.1.3、简化开发

目前,我们需要在 Servlet 容器中分别指定两个配置类(SpringMVC 和 Spring),能不能再简化一些呢? 答案是可以的,我们只需要继承抽象类  AbstractAnnotationConfigDispatcherServletInitializer 即可:

本节注解说明

名称位置作用参数
@ComponentScan类注解类定义上方excludeFilters:排除扫描路径中加载的bean,需要指定类别(type)和具体项(classes) includeFilters:加载指定的bean,需要指定类别(type)和具体项(classes)

5、Postman

        目前我们测试请求都是直接在地址栏输入参数,但是这种方式只能模拟 get 请求,对于 post 请求我们还需要创建表单,对于更复杂的 Ajax 请求我们不只需要表单,还是配置 JavaScript 代码来完成异步提交。

        postman 的作用就是用来模拟各种网页请求的,所以作为一个后端程序员,我们就再也不用去写一些恶心的前端代码去测试了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/541898.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

有序二叉树的增删改查(源代码讲解)

有序二叉树的相关实体类 TreeNode类 二叉树结点类&#xff0c;包含三个属性&#xff1a;value&#xff0c;leftChild&#xff0c;rightChild 有序二叉树类就包括这样一个根节点 剩下的getter和setter方法&#xff0c;有参无参构造&#xff0c;toString方法都是老生长谈&…

Zotero插件ZotCard中AI-NNDL文献笔记卡分享及卡片使用方法

一、卡片社区分享 github&#xff1a;ZotCard插件AI-NNDL论文卡片模板 Issue #67 018/zotcard (github.com) 二、卡片效果预览 ZotCard插件AI-NNDL论文卡片模板是关于人工智能神经网络与深度学习论文的笔记卡片&#xff0c;效果预览如下图&#xff1a; 三、卡片代码 经过了…

【MySQL】MySQL在Centos 7环境安装

目录 准备工作 第一步&#xff1a;卸载不要的环境 第二步&#xff1a;下载官方的mysql 第三步 上传到Linux中 第四步 安装 正式安装 启动 ​编辑 登录 准备工作 第一步&#xff1a;卸载不要的环境 使用root进行安装 如果是普通用户&#xff0c;使用 su - 命令&#…

a == 1 a== 2 a== 3 返回 true ?

1. 前言 下面这道题是 阿里、百度、腾讯 三个大厂都出过的面试题&#xff0c;一个前端同事跳槽面试也被问了这道题 // &#xff1f; 位置应该怎么写&#xff0c;才能输出 trueconst a ?console.log(a 1 && a 2 && a 3) 看了大厂的面试题会对面试官的精神…

r3live 使用前提 雷达-相机外参标定 livox_camera_lidar_calibration

标定的是相机到雷达的,R3live下面配置的雷达到相机的,所以要把得到外参旋转矩阵求逆,再填入,平移矩阵则取负 港科大livox_camera_calib虽然操作方便&#xff0c;但是使用mid360雷达会有视角问题&#xff08;投影三维点到相机&#xff09;&#xff0c;尝试了很多场景&#xff0c…

蓝牙介绍 1

大纲 蓝牙简介 BLE协议栈 开发环境搭建I OSAL层工作原理 UART实验 LED实验、ADC实验 深入了解GAP和GATT 添加特征值-主从机通信实验 无线网络开发 进阶学习 蓝牙智能手环介绍 1 蓝牙4.0简介 为什么需要蓝牙技术 wifi功耗太高&#xff0c;电池无法支撑 短距离、小电池支持的设…

[论文翻译]GLU Variants Improve Transformer

引言 今天带来一篇短小精悍的论文GLU Variants Improve Transformer笔记&#xff0c;作者提出了GLU1的一种变体。 GLU(Gated Linear Units,门控线性单元)由两个线性投影的逐元素乘积组成&#xff0c;其中一个首先经过sigmoid函数。GLU的变体是可能生效的&#xff0c;可以使用…

Leetcode刷题之删除有序数组的重复项

一、题目描述 删除有序数组的重复项 给你一个 非严格递增排列 的数组 nums &#xff0c;请你 原地 删除重复出现的元素&#xff0c;使每个元素 只出现一次 &#xff0c;返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。然后返回 nums 中唯一元素的个数。 考虑 nums…

【计算机网络】ip子网划分--超详细例题解析

Hello!这一篇主要是计算机网络中的ip地址子网划分的例题&#xff0c;这里例举了四个题型。保证即便从0也可以掌握&#xff01;(前面是一些预备知识&#xff0c;不熟悉的小伙伴一定要看下学习下哦&#xff5e;) 这也是博主的学习过程&#xff0c;做题中仅仅我的理解哦。若文章中…

1.Hexo安装和环境搭建引导

Hexo是一个依赖于一个名为nodejs的程序 因此安装它的方式在Mac和Windows上实际上是一样的 为了在电脑上安装Hexo 需要做两件事 nodejs&#xff0c;基本上是hexo依赖运行的JavaScript框架 Node.js — Run JavaScript Everywheregit&#xff0c;是一个程序&#xff0c;用来管理电…

前端知识学习笔记-六(vue)

简介 Vue是前端优秀框架是一套用于构建用户界面的渐进式框架 Vue优点 Vue是目前前端最火的框架之一 Vue是目前企业技术栈中要求的知识点 vue可以提升开发体验 Vue学习难度较低 Vue开发前准备 一、nodejs环境 Nodejs简介 Nodejs诞生于2009年&#xff0c;主攻服务器方向&#x…

IDEA中sql语句智能提示设置

选中一句sql语句&#xff0c;点击鼠标右键 指定数据库

机器学习入门实战1:鸢尾花分类

花名&#xff1a;鸢尾花 别名&#xff1a;爱丽丝、蓝蝴蝶、紫蝴蝶 花语&#xff1a;爱的使者、长久思念 花期&#xff1a;5-6月 颜色&#xff1a;蓝色、紫色、白色、粉色等 鸢尾花主要色彩为蓝紫色&#xff0c;有“蓝色妖姬”的美誉&#xff0c;因花瓣形如鸢鸟尾巴而得名&#…

vi编辑器

目录 一、文本编辑器vi命令 1.作用&#xff1a; 2.vi和vim 二、vi编辑器的三种模式 三、输入模式 四、命令模式 五、末行模式 一、文本编辑器vi命令 1.作用&#xff1a; 创建或修改文本文件 维护Linux系统中的各种配置文件 2.vi和vim vi:类UNIX操作系统的默认文本编辑器…

揭示空间依赖性:运用先进自相关技术挖掘地理数据中的规律

原文地址&#xff1a;deciphering-spatial-dependence-unlocking-patterns-in-geographical-data-through-advanced 2024 年 4 月 9 日 简介 空间自相关分析是用于衡量和分析一组空间数据点在地理空间中相关程度的统计方法。该技术是空间分析和地理信息系统 (GIS) 的组成部分…

第十五届蓝桥杯c++b组赛后复盘和真题展示

题目变成八道了&#xff0c;分数一百分可能&#xff0c;感觉拿奖难度还是很高 第一题是一个简单的握手问题 答案算出来1204&#xff0c;纯手写 第二题是 物理题 纯蒙&#xff0c;随便猜了个轨迹&#xff0c;答案具体忘了&#xff0c;最后是 .45 第三题暴力 第四题 我是傻逼…

分布式技术--------------ELK大规模日志实时收集分析系统

目录 一、ELK日志分析系统 1.1ELK介绍 1.2ELK各组件介绍 1.2.1ElasticSearch 1.2.2Kiabana 1.2.3Logstash 1.2.4可以添加的其它组件 1.2.4.1Filebeat filebeat 结合logstash 带来好处 1.2.4.2缓存/消息队列&#xff08;redis、kafka、RabbitMQ等&#xff09; 1.2.4.…

【C++】详解类的--封装思想(让你丝滑的从C语言过度到C++!!)

目录 一、前言 二、【面向过程】 与 【面向对象】 三、结构体 与 类 &#x1f34e;C中结构体的变化 &#x1f349;C中结构体的具体使用 &#x1f350;结构体 --> 类 ✨类-----语法格式&#xff1a; ✨类的两种定义方式&#xff1a; 四、类的访问限定符及封装【⭐】 …

python--4函数def,本质、值传递、引用传递、默认值参数、*参数名、**变量、lambda [参数]: 函数、偏函数、递归

学习目标&#xff1a; 函数def,本质、值传递、引用传递、默认值参数、*参数名、**变量、lambda [参数]: 函数、偏函数、递归 学习内容&#xff1a; 函数def,本质、值传递、引用传递、默认值参数、*参数名、**变量、lambda [参数]: 函数、偏函数、递归 目录 学习目标&…

【零基础学鸿蒙】ArkTS开发语言介绍

在之前的教学中&#xff0c;我们学习了下载安装DevEco Studio等相关知识。今天开始讲ArkTS 1.1 TypeScrip快速入门 学习TypeScript对于HarmonyOS应用开发至关重要。在HarmonyOS中&#xff0c;主力编程语言为ArKTS&#xff0c;它是基于TypeScript的一种语言&#xff0c;其通过…