1. SpringMVC 简介

1. SpringMVC 概述

SpringMVC 与 Servlet 功能等同,均属于 Web 层开发技术。SpringMVC 是 Spring 框架的一部分。

对于 SpringMVC,主要学习如下内容:

  • SpringMVC 简介
  • 请求与响应
  • REST 风格
  • SSM 整合(注解版)
  • 拦截器

SpringMVC 是处于 Web 层的框架,所以其主要的作用就是用来接收前端发过来的请求和数据然后进行处理,并将处理的结果响应给前端,所以如何处理请求和响应是 SpringMVC 中非常重要的一块内容。

REST 是一种软件架构风格,可以降低开发的复杂性,提高系统的可伸缩性,后期的应用也是非常广泛。

SSM 整合是把咱们所学习的 SpringMVC+Spring+Mybatis 整合在一起来完成业务开发,是对三个框架的综合应用。

对于 SpringMVC 的学习,最终要达成的目标:
(1) 掌握基于 SpringMVC 获取请求参数和响应 json 数据操作。
(2) 熟练应用基于 REST 风格的请求路径设置与参数传递。
(3) 能够根据实际业务建立前后端开发通信协议并进行实现。
(4) 基于 SSM 整合技术开发任意业务模块功能。

学习 SpringMVC 前,先回顾一下现在 web 程序是如何做的。现在的 web 程序大都基于三层架构来实现:

在这里插入图片描述

如上图,Web 程序通过浏览器访问页面,前端页面使用异步提交的方式发送请求到后端服务器,后端服务器采用三层架构——表现层、业务层、数据层进行开发。页面发送的请求由表现层接收,获取用户的请求参数后,将参数传递给业务层,再由业务层访问数据层,得到用户需要访问的数据后,将数据返回给表现层。表现层拿到数据后,将数据转换成 json 格式发送给前端页面,前端页面接收数据后,解析数据并组织成用户最终浏览的页面信息交给浏览器。

在这里插入图片描述

初学时,数据层采用的是 jdbc 技术,后来 Mybatis 框架将其取代;表现层采用的是 servlet 技术,现在将要学习的 SpringMVC 框架可以将其取代。

介绍了这么多,对 SpringMVC 进行一个定义:

SpringMVC 是一种基于Java 实现 MVC 模型的轻量级 Web 框架。

优点:使用简单、开发便捷(相比于Servlet);灵活性强。

2. SpringMVC 入门案例

2.1 入门案例

在这里插入图片描述

(1) 创建项目

创建 Maven 项目。

在这里插入图片描述
补全目录结构,因为使用骨架创建的项目结构不完整,需要手动补全。

在这里插入图片描述
(2) 导入依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

  <modelVersion>4.0.0</modelVersion>
  <packaging>war</packaging>

  <name>springmvc01_quickstart</name>
  <groupId>com.itheima</groupId>
  <artifactId>springmvc01_quickstart</artifactId>
  <version>1.0-SNAPSHOT</version>

  <properties>
    <maven.compiler.source>8</maven.compiler.source>
    <maven.compiler.target>8</maven.compiler.target>
  </properties>

  <dependencies>
    <!--导入springmvc与servlet的依赖-->
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>3.1.0</version>
      <scope>provided</scope><!--防止与tomcat插件冲突-->
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>5.2.10.RELEASE</version>
    </dependency>
  </dependencies>
  
  <!--tomcat插件-->
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.tomcat.maven</groupId>
        <artifactId>tomcat7-maven-plugin</artifactId>
        <version>2.1</version>
        <configuration>
          <port>80</port><!--tomcat端口号-->
          <path>/</path><!--虚拟目录-->
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>

说明:servlet 的依赖为什么需要添加<scope>provided</scope>

scope 是 maven 中 jar 包依赖作用范围的描述,如果不设置默认是在编译、运行、测试时均有效。

如果运行有效的话就会和 tomcat 中的 servlet-api 包发生冲突,导致启动报错。

provided 代表的是该包只在编译和测试时用,运行时无效,直接使用 tomcat 中的,就避免了冲突。

(3) 创建 Controller 类

//使用Controller定义bean
@Controller
public class UserController {
    // 当前操作的请求映射路径:用户发出哪个请求能调用到这个方法
    @RequestMapping("/save")
    // 设置当前操作的返回值类型
    // 把返回的东西整体作为响应的内容给到外面
    @ResponseBody//设置当前控制器方法响应内容为当前返回值,无需解析
    // 处理请求的方法
    // 返回值为String:执行完这个方法,要对外返回json数据
    public String save(){
        System.out.println("user save ...");
        return "{'module':'springmvc'}";
    }
}

(4) 创建配置类

@Configuration
//加载 controller 对应的 bean
@ComponentScan("com.itheima.controller")
public class SpringMvcConfig {
}

(5) 使用配置类替换 web.xml
将web.xml删除,换成ServletContainersInitConfig

// 定义一个servlet容器启动的配置类
// 要继承AbstractDispatcherServletInitializer
public class ServletControllerInitConfig extends AbstractDispatcherServletInitializer {
    //加载springMVC容器的配置
    //tomcat服务器启动时,就能加载SpringMVC配置类了
    @Override
    protected WebApplicationContext createServletApplicationContext() {
        //加载springMVC的配置类
        AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
        ctx.register(SpringMvcConfig.class);
        return ctx;
    }
    //设置哪些请求由springMVC处理
    @Override
    protected String[] getServletMappings() {
        //所有请求都由springMVC处理
        return new String[]{"/"};
    }
    //加载spring容器配置
    //现在只用springMVC容器,所以这个方法不用管,直接返回null
    @Override
    protected WebApplicationContext createRootApplicationContext() {
        return null;
    }
}

(6) 配置 tomcat 环境
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

(7) 运行项目后,用浏览器访问

在这里插入图片描述
idea 控制台也打印出了:user save …

SpringMVC 入门程序开发总结(1+N):

一次性工作

  • 创建工程,设置服务器,加载工程
  • 导入依赖
  • 创建 web 容器启动类,加载 SpringMVC 配置,并设置SpringMVC 请求拦截路径
  • SpringMVC 核心配置类(设置配置类,扫描 controller 包,加载 Controller 控制器 bean)

多次工作

  • 定义处理请求的控制器类
  • 定义处理请求的控制器方法,并配置映射路径(@RequestMapping)与返回 json 数据(@ResponseBody)

如:直接在 UserController 中加入如下代码,就可以扩展功能。

@RequestMapping("/delete")
@ResponseBody
public String delete(){
    System.out.println("user delete ...");
    return "{'module':'springmvc delete'}";
}

2.2 入门案例工作流程

在这里插入图片描述

3. bean 加载控制

在这里插入图片描述

SpringMVC 需要加载的 bean:表现层的 bean,也就是 controller 包下的。

Spring 需要加载的bean:
业务 bean(Service)
功能 bean(DataSource、SqlSessionFactoryBean、MapperScannerConfigurer 等)

分析清楚谁该管哪些 bean 以后,要解决的问题就是如何让 Spring 和 SpringMVC 分开加载各自的 bean。

在 SpringMVC 的配置类 SpringMvcConfig 中使用注解@ComponentScan,只需将扫描范围设置到 controller,如:

在这里插入图片描述

之前在 Spring 的配置类 SpringConfig 中使用注解@ComponentScan 时,扫描的范围其实已经包含了 controller,如:

在这里插入图片描述
实际上,应该避免 Spring 错误地加载到 SpringMVC 的 bean,下面就来解决这个问题。

解决方案有三种:

① Spring 加载 bean 时,设定扫描范围为精准范围,例如 service 包、dao 包等(主要用这种)。

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

注意:dao 包下的类的对象是使用 mybatis 自动代理的方式创建的,这个对象不是我们自己创建出来的,所以写不写 com.itheima.dao 都不影响对应 bean 的加载,但是写上更好(因为不用 mybatis 自动代理时可能会需要)。

② Spring 加载 bean 时,设定扫描范围为 com.itheima,排除掉 controller 包中的 bean。

@Configuration
//扫描com.itheima下的类,以加载bean
//按注解过滤,过滤掉带有@Controller注解的类
@ComponentScan(value = "com.itheima",
        excludeFilters = @ComponentScan.Filter(
                type = FilterType.ANNOTATION,
                classes = Controller.class
        )
)
public class SpringConfig {
}
  • excludeFilters:排除扫描路径中加载的 bean。
  • includeFilters:加载指定的 bean,在现有基础上追加。

SpringConfig 扫描时,如果某个类上有 @Configuration 注解,那么这个类也会被扫描,同时它里面的 bean 也会被加载。

SpringMvcConfig 上就有一个@ComponentScan。虽然 SpringConfig 的扫描过滤掉了 controller 类,但又通过 SpringMvcConfig 把 controller 类给扫描进来了。
解决方案:把 SpringMvcConfig 移出 Spring 配置类的扫描范围。如:可以将 SpringConfig、SpringMvcConfig 移动到 com 下。

③ 不区分 Spring 与 SpringMVC 的环境,加载到同一个环境中(了解即可)

最后一个问题,有了 Spring 的配置类,要想在 tomcat 服务器启动将其加载,我们需要修改 ServletContainersInitConfig。

// 定义一个servlet容器启动的配置类
// 要继承AbstractDispatcherServletInitializer
public class ServletControllerInitConfig extends AbstractDispatcherServletInitializer {
    //加载springMVC容器的配置
    //tomcat服务器启动时,就能加载SpringMVC配置类了
    @Override
    protected WebApplicationContext createServletApplicationContext() {
        //加载springMVC的配置类
        AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
        ctx.register(SpringMvcConfig.class);
        return ctx;
    }
    //设置哪些请求由springMVC处理
    @Override
    protected String[] getServletMappings() {
        //所有请求都由springMVC处理
        return new String[]{"/"};
    }
    //加载spring容器配置
    @Override
    protected WebApplicationContext createRootApplicationContext() {
        //加载spring的配置类
        AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
        ctx.register(SpringConfig.class);
        return ctx;
    }
}

对于上述的配置方式,Spring 还提供了一种更简单的配置方式,可以不用再去创建
AnnotationConfigWebApplicationContext 对象,不用手动register 对应的配置类,如何实现?

// 定义一个servlet容器启动的配置类
// 要继承AbstractAnnotationConfigDispatcherServletInitializer
public class ServletControllerInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
    //加载Spring配置类
    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[]{SpringConfig.class};
    }
    //加载SpringMVC配置类
    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class[]{SpringMvcConfig.class};
    }
    //设置哪些请求由springMVC处理
    @Override
    protected String[] getServletMappings() {
        //所有请求都由springMVC处理
        return new String[]{"/"};
    }
}

4. PostMan 工具

代码编写完后要想测试,只需要打开浏览器直接输入地址发送请求即可。发送的是 GET 请求可以直接使用浏览器,但是如果要发送的是 POST 请求呢?

如果要求发送的是 POST 请求,就得准备页面,并在页面上准备 form 表单,测试起来比较麻烦。所以就需要借助一些第三方工具,如 PostMan。

PostMan 是一款网页调试与发送网页 HTTP 请求的 Chrome 插件,常用于进行接口测试。

(1) 创建 WorkSpace 工作空间

在这里插入图片描述

(2) 工作空间的名称

在这里插入图片描述
(3) 选择请求方式

在这里插入图片描述

在这里插入图片描述

(4) 发送请求(相当于在浏览器发送请求)

在这里插入图片描述
数据效果:

在这里插入图片描述

页面效果:

在这里插入图片描述
(5) 同样地,可以向百度发请求:

在这里插入图片描述

(6) 保存当前请求(ctrl+s后)

在这里插入图片描述

注意:第一次请求需要创建一个新的目录,后面就不需要创建新目录,直接保存到已经创建好的目录即可。

对于 PostMan 如果觉得字小不好看,可以使用 ctrl+“=” 调大,ctrl+“-” 调小。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值