一篇文章带你掌握主流服务层框架——SpringMVC

在之前的文章中我们已经学习了Spring的基本内容,SpringMVC隶属于Spring的一部分内容

但由于SpringMVC完全针对于服务层使用,所以我们在介绍时常常把SpringMVC单独当作一个大章节来学习

温馨提醒:在学习SpringMVC前请确保已学习Spring内容

SpringMVC简介

首先我们先来简单了解一下SpringMVC:

  • SpringMVC是一种基于Java实现MVC模型的轻量级Web框架
  • SpringMVC致力于服务层,同Servlet一样应用于服务层,用于服务层开发
  • SpringMVC隶属于Spring,同样具有简化代码,使用简单,开发便捷,灵活性强的优点

SpringMVC入门案例

在未学习SpringMVC之前,我们的服务端开发通常采用Servlet:

  1. package com.itheima.web.servlet.old;
  2. import com.alibaba.fastjson.JSON;
  3. import com.itheima.pojo.Brand;
  4. import com.itheima.service.BrandService;
  5. import com.itheima.service.impl.BrandServiceImpl;
  6. import javax.servlet.ServletException;
  7. import javax.servlet.annotation.WebServlet;
  8. import javax.servlet.http.HttpServlet;
  9. import javax.servlet.http.HttpServletRequest;
  10. import javax.servlet.http.HttpServletResponse;
  11. import java.io.BufferedReader;
  12. import java.io.IOException;
  13. import java.util.List;
  14. //@WebServlet("/addServlet")
  15. public class AddServlet extends HttpServlet {
  16. private BrandService brandService = new BrandServiceImpl();
  17. @Override
  18. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  19. //1. 接收品牌数据
  20. BufferedReader br = request.getReader();
  21. String params = br.readLine();//json字符串
  22. //转为Brand对象
  23. Brand brand = JSON.parseObject(params, Brand.class);
  24. //2. 调用service添加
  25. brandService.add(brand);
  26. //3. 响应成功的标识
  27. response.getWriter().write("success");
  28. }
  29. @Override
  30. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  31. this.doGet(request, response);
  32. }
  33. }

我们可以注意到其过程非常繁琐,因为我们需要获取参数并进行类型转换,包括添加至Service等过程

但是SpringMVC秉承着简化代码的原则,将大部分内容转化为Java代码进行封装,大大减少了繁琐的过程

接下来我们来介绍SpringMVC版:

  1. 导入jar包
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  4. <modelVersion>4.0.0</modelVersion>
  5. <groupId>com.itheima</groupId>
  6. <artifactId>springmvc_01_quickstart</artifactId>
  7. <version>1.0-SNAPSHOT</version>
  8. <packaging>war</packaging>
  9. <dependencies>
  10. <!-- servlet坐标-->
  11. <dependency>
  12. <groupId>javax.servlet</groupId>
  13. <artifactId>javax.servlet-api</artifactId>
  14. <version>3.1.0</version>
  15. <scope>provided</scope>
  16. </dependency>
  17. <!-- SpringMVC坐标-->
  18. <dependency>
  19. <groupId>org.springframework</groupId>
  20. <artifactId>spring-webmvc</artifactId>
  21. <version>5.2.10.RELEASE</version>
  22. </dependency>
  23. </dependencies>
  24. <!--Tomcat配置-->
  25. <build>
  26. <plugins>
  27. <plugin>
  28. <groupId>org.apache.tomcat.maven</groupId>
  29. <artifactId>tomcat7-maven-plugin</artifactId>
  30. <version>2.1</version>
  31. <configuration>
  32. <port>80</port>
  33. <path>/</path>
  34. </configuration>
  35. </plugin>
  36. </plugins>
  37. </build>
  38. </project>
  1. 创建SpringMVC控制类(等同于Servlet类)
  1. package com.itheima.controller;
  2. import org.springframework.stereotype.Controller;
  3. import org.springframework.web.bind.annotation.RequestMapping;
  4. import org.springframework.web.bind.annotation.ResponseBody;
  5. //定义表现层控制器bean
  6. @Controller
  7. public class UserController {
  8. //设置映射路径为/save,即外部访问路径
  9. @RequestMapping("/save")
  10. //设置当前操作返回结果为指定json数据(本质上是一个字符串信息)
  11. @ResponseBody
  12. public String save(){
  13. System.out.println("user save ...");
  14. return "{'info':'springmvc'}";
  15. }
  16. //设置映射路径为/delete,即外部访问路径
  17. @RequestMapping("/delete")
  18. @ResponseBody
  19. public String delete(){
  20. System.out.println("user save ...");
  21. return "{'info':'springmvc'}";
  22. }
  23. }
  1. 初始化SpringMVC环境(同Spring一样创建Config配置Java类)
  1. package com.itheima.config;
  2. import org.springframework.context.annotation.ComponentScan;
  3. import org.springframework.context.annotation.Configuration;
  4. //springmvc配置类,本质上还是一个spring配置类
  5. @Configuration
  6. @ComponentScan("com.itheima.controller")
  7. public class SpringMvcConfig {
  8. }
  1. 初始化Servlet容器,加载SpringMVC环境,并设置SpringMVC技术处理的请求
  1. /*
  2. 我们服务层的实际操作都是放置于Servlet容器中
  3. 我们配置的SpringMVC和Spring环境都是用于服务层,所以我们需要把相关Config加载仅Servlet容器中
  4. */
  5. package com.itheima.config;
  6. import org.springframework.web.context.WebApplicationContext;
  7. import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
  8. import org.springframework.web.servlet.support.AbstractDispatcherServletInitializer;
  9. // web容器配置类
  10. // AbstractDispatcherServletInitializer是SpringMVC为我们设置好的类,继承并实现相关方法即可
  11. public class ServletContainersInitConfig extends AbstractDispatcherServletInitializer {
  12. //加载springmvc配置类,产生springmvc容器(本质还是spring容器)
  13. protected WebApplicationContext createServletApplicationContext() {
  14. //初始化WebApplicationContext对象
  15. AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
  16. //加载指定配置类
  17. ctx.register(SpringMvcConfig.class);
  18. return ctx;
  19. }
  20. //设置由springmvc控制器处理的请求映射路径
  21. protected String[] getServletMappings() {
  22. return new String[]{"/"};
  23. }
  24. //加载spring配置类
  25. protected WebApplicationContext createRootApplicationContext() {
  26. return null;
  27. }
  28. }

我们对上述新的内容进行解析:

  1. @Controller

    • 名称:@Controller

    • 类型:类注解

    • 位置:SpringMVC控制类定义上方

    • 作用:设定SpringMVC的核心控制器Bean

  2. @RequestMapping

    • 名称:@RequestMapping

    • 类型:方法注解

    • 位置:SpringMVC控制器方法定义上方

    • 作用:设置当前控制器方法请求访问路径

    • 相关属性:value(请求访问路径)

  3. @ResponseBody

    • 名称:@ResponseBody

    • 类型:方法注释

    • 位置:SpringMVC控制器方法定义上方

    • 作用:设置当前控制器方法响应内容为当前返回值,无需解析

  4. AbstractDispatcherServletInitializer类

    • AbstractDispatcherServletInitializer是SpringMVC提供的快速初始化Web3.0容器的抽象类
    • AbstractDispatcherServletInitializer提供三个接口方法供用户实现
    • createServletApplicationContext方法用于创建Servlet容器时,加载SpringMVC对应的Bean并放入
    • AnnotationConfigWebApplicationContext的作用范围对应整个Web容器范围,必须使用WebApplicationcontext类型

最后我们总结一下上述操作的出现频率:

  • 一次性工作

    • 创建工程,设置服务器,加载工程
    • 导入坐标
    • 创建Web容器启动类,加载SpringMVC配置,并设置SpringMVC请求拦截路径
    • SpringMVC核心配置类(设置配置类,扫描controller包,加载Controller控制器Bean)
  • 常态工作
    • 定义处理请求的控制类
    • 定义处理请求的操作方法,并设置映射路径(@RequestMapper)与返回Json数据(@ResponseBody)

SpringMVC工作流程

在分析SpringMVC工作流程前,我们需要知道服务层是由下面的框架组成的:

启动服务器初始化过程:

  1. 服务器启动,执行ServletContainersInitConfig类,初始化Web容器
  2. 执行createServletApplicationContext方法,创建了WebApplicationContext对象
  3. 加载SpringMvcConfig
  4. 执行@ComponentScan加载对应的bean
  5. 加载UserController,每个@RequestMapping的名称对应一个具体的方法
  6. 执行getServletMappings方法,定义所有的请求都通过SpringMVC

单次请求过程:

  1. 发送请求localhost/save
  2. Web容器发现所有请求都经过SpirngMVC,将请求交给SpringMVC处理
  3. 解析请求路径/save
  4. 由/save匹配执行对应的方法save()
  5. 执行save()
  6. 检测到有@ResponseBody直接将save()方法的返回值作为响应求体返回给请求方

SpringMVC加载控制

在学习SpringMVC之后,我们的Bean的范围逐渐变大:

  • SpringMVC相关bean(表现层bean)
  • Spring相关bean(业务层Service,功能DataSource等)

但是我们在使用时,需要区分相关bean的导入路径:

  • SpringMVC加载的bean对应的包均在com.itheima.controller包内
  • Spring加载的bean却包含有多个文件夹

因而我们给出两种方法来解决Spring的扫描问题:

  1. Spring加载的bean设定范围为com.itheima,并排除掉controller包内的bean
  1. package com.itheima.config;
  2. import org.springframework.context.annotation.ComponentScan;
  3. import org.springframework.context.annotation.Configuration;
  4. import org.springframework.context.annotation.FilterType;
  5. import org.springframework.stereotype.Controller;
  6. @Configuration
  7. /*
  8. @ComponentScan注解设置扫描范围
  9. @ComponentScan中包含有value,excludeFilters属性
  10. value:用于控制扫描范围
  11. excludeFilters:用于控制排除范围,需要采用@ComponentScan.Filter过滤器
  12. type:设置排除规则,当前使用按照bean定义时的注解类型进行排除
  13. classes属性:设置排除的具体注解类,当前设置排除@Controller定义的bean
  14. */
  15. @ComponentScan(value="com.itheima",
  16. excludeFilters = @ComponentScan.Filter(
  17. type = FilterType.ANNOTATION,
  18. classes = Controller.class
  19. )
  20. )
  21. public class SpringConfig {
  22. }
  23. /*
  24. 这里做一个小补充内容:
  25. @ComponentScan中除了excludeFilters,还包括有includeFilters
  26. includeFilters:加载指定的bean,需要指定类型(type)和具体项(classes)
  27. */
  1. Spring加载的bean设定范围为精准范围,例如service包,dao包等
  1. package com.itheima.config;
  2. import org.springframework.context.annotation.ComponentScan;
  3. import org.springframework.context.annotation.Configuration;
  4. import org.springframework.context.annotation.FilterType;
  5. import org.springframework.stereotype.Controller;
  6. @Configuration
  7. @ComponentScan({"com.itheima.service","com.itheima.dao"})
  8. public class SpringConfig {
  9. }

Servlet容器简化写法

我们的Servlet容器中可以定义Spring和SpringMVC的配置文件

  1. package com.itheima.config;
  2. import org.springframework.web.context.WebApplicationContext;
  3. import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
  4. import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
  5. import org.springframework.web.servlet.support.AbstractDispatcherServletInitializer;
  6. public class ServletContainersInitConfig extends AbstractDispatcherServletInitializer {
  7. // 配置SpringMVC配置文件
  8. protected WebApplicationContext createServletApplicationContext() {
  9. AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
  10. ctx.register(SpringMvcConfig.class);
  11. return ctx;
  12. }
  13. // 配置Spring配置文件
  14. protected WebApplicationContext createRootApplicationContext() {
  15. AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
  16. ctx.register(SpringConfig.class);
  17. return ctx;
  18. }
  19. // 配置拦截路径
  20. protected String[] getServletMappings() {
  21. return new String[]{"/"};
  22. }
  23. }

我们可以注意到:

Spring和SpringMVC导入方法中均采用AnnotationConfigWebApplicationContext来创建对象

两者之间的区别仅仅是class包的不同

Spring给了我们一种新的继承类用于简化开发:

  1. package com.itheima.config;
  2. import org.springframework.web.context.WebApplicationContext;
  3. import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
  4. import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
  5. import org.springframework.web.servlet.support.AbstractDispatcherServletInitializer;
  6. //web配置类简化开发,仅设置配置类类名即可
  7. public class ServletContainersInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
  8. protected Class<?>[] getRootConfigClasses() {
  9. return new Class[]{SpringConfig.class};
  10. }
  11. protected Class<?>[] getServletConfigClasses() {
  12. return new Class[]{SpringMvcConfig.class};
  13. }
  14. protected String[] getServletMappings() {
  15. return new String[]{"/"};
  16. }
  17. }

注意:

AbstractAnnotationConfigDispatcherServletInitializer是createServletApplicationContext的继承类

我们同样继承它的三个方法,但这次我们只需要在里面标明相关类和路径即可

常用工具推荐Postman

在我们的SpringMVC中岔开一个话题:

  • 关于我们的网页调试的复杂性

我们在一个网页开发中,会不断的调试网页,通过各种路径反复查询或者采用不同的访问方式(GET/POST)

如果我们采用正常的网页进行测试,无疑会出现非常麻烦的步骤

所以我们推荐采用Postman软件,下面我们将会简单做一下介绍

Postman链接

首先为大家附上链接:

Postman操作讲解

在了解操作前,我们需要明白Postman的作用:

  • 用于分类存储网页请求
  • 用于发送请求进行测试

关于安装注册的过程我们不再赘述

Postman页面展示

我们先来查看Postman的主页:

首先我们可以看到左上角的Workspaces,这个是最大的分类空间

我们可以看到左上角SpringMVC,这是我所创建的WorkSpaces,关于我在SpringMVC所做的网页测试部分将都在这里进行

除此之外,我们可以看到右侧的DEMO1,以及内部的测试用例文件夹,以及项目save

以上就是我们的Postman的基本页面

Postman具体使用

我们的Postman的具体使用流程如下:

  1. 创建新的Workspaces

  1. 选定主界面,创建对应文件夹

  1. 创建项目(点击中间区域的加号)

  1. 书写项目内容(GET可以更换其他类型,后面书写URL,下方key,value书写传递数据)

  1. 下方的数据传递可以更换类型,例如更换为body体的raw来书写JSON格式

  1. 书写后保存到相应列表并标注名称

到这里,我们Postman的基本使用基本就结束了,到后面我们会对具体内容做具体补充~

SpringMVC设置请求与响应

SpringMVC和Servlet同属于服务层的工具,那么必不可少的就是请求与响应的反馈问题

接下来我们将一一介绍请求与响应的相关知识

请求映射路径设置

首先我们先来想一想我们之前的路径设置是否有那么一点点缺陷?

  1. // Book的服务层
  2. package com.itheima.controller;
  3. import org.springframework.stereotype.Controller;
  4. import org.springframework.web.bind.annotation.RequestMapping;
  5. import org.springframework.web.bind.annotation.ResponseBody;
  6. @Controller
  7. public class BookController {
  8. //请求路径映射
  9. @RequestMapping("/save")
  10. @ResponseBody
  11. public String save(){
  12. System.out.println("book save ...");
  13. return "{'module':'book save'}";
  14. }
  15. }
  1. // User的服务层
  2. package com.itheima.controller;
  3. import org.springframework.stereotype.Controller;
  4. import org.springframework.web.bind.annotation.RequestMapping;
  5. import org.springframework.web.bind.annotation.RequestParam;
  6. import org.springframework.web.bind.annotation.ResponseBody;
  7. @Controller
  8. public class UserController {
  9. //请求路径映射
  10. @RequestMapping("/save")
  11. @ResponseBody
  12. public String save(){
  13. System.out.println("user save ...");
  14. return "{'module':'user save'}";
  15. }
  16. //请求路径映射
  17. @RequestMapping("/delete")
  18. @ResponseBody
  19. public String delete(){
  20. System.out.println("user delete ...");
  21. return "{'module':'user delete'}";
  22. }
  23. }

我们可以注意到我们的单个项目中不可能只包括有一个服务层

但我们的请求映射路径却只是简单设计为相同的名称,就会导致我们访问该页面时,系统无法匹配

所以我们需要给他们采用不同的映射路径,我们常有的操作是直接在前面加上一层该类的路径名:

  1. package com.itheima.controller;
  2. import org.springframework.stereotype.Controller;
  3. import org.springframework.web.bind.annotation.RequestMapping;
  4. import org.springframework.web.bind.annotation.ResponseBody;
  5. @Controller
  6. public class BookController {
  7. //请求路径映射
  8. @RequestMapping("/book/save")
  9. @ResponseBody
  10. public String save(){
  11. System.out.println("book save ...");
  12. return "{'module':'book save'}";
  13. }
  14. }

但当项目逐渐增多,我们多次书写路径名就有可能导致错误,所以我们采用类注解@RequestMapping来解决:

  1. package com.itheima.controller;
  2. import org.springframework.stereotype.Controller;
  3. import org.springframework.web.bind.annotation.RequestMapping;
  4. import org.springframework.web.bind.annotation.RequestParam;
  5. import org.springframework.web.bind.annotation.ResponseBody;
  6. @Controller
  7. //类上方配置的请求映射与方法上面配置的请求映射连接在一起,形成完整的请求映射路径
  8. @RequestMapping("/user")
  9. public class UserController {
  10. //请求路径映射
  11. @RequestMapping("/save")
  12. @ResponseBody
  13. public String save(){
  14. System.out.println("user save ...");
  15. return "{'module':'user save'}";
  16. }
  17. //请求路径映射
  18. @RequestMapping("/delete")
  19. @ResponseBody
  20. public String delete(){
  21. System.out.println("user delete ...");
  22. return "{'module':'user delete'}";
  23. }
  24. }

注意:@RequestMapping不仅仅可以用于方法表示映射,也可以用于整个Bean类中表示映射前缀

参数传递问题

关于参数传递我们从三个方面来讲解:

  • 传递方式
  • 传递参数类型
  • 特殊参数类型

按传递方式

我们的传递方式通常采用GET或者POST方式

但在前面的学习中我们可以知道我们的传递方式是有不同的,我们在Postman的书写形式也是不同的

例如我们先给出一个简单的参数传递函数

  1. package com.itheima.controller;
  2. import com.itheima.domain.User;
  3. import org.springframework.format.annotation.DateTimeFormat;
  4. import org.springframework.stereotype.Controller;
  5. import org.springframework.web.bind.annotation.RequestBody;
  6. import org.springframework.web.bind.annotation.RequestMapping;
  7. import org.springframework.web.bind.annotation.RequestParam;
  8. import org.springframework.web.bind.annotation.ResponseBody;
  9. import java.util.Arrays;
  10. import java.util.Date;
  11. import java.util.List;
  12. //请求参数
  13. @Controller
  14. public class UserController {
  15. //普通参数:请求参数与形参名称对应即可完成参数传递
  16. @RequestMapping("/commonParam")
  17. @ResponseBody
  18. public String commonParam(String name ,int age){
  19. System.out.println("普通参数传递 name ==> "+name);
  20. System.out.println("普通参数传递 age ==> "+age);
  21. return "{'module':'common param'}";
  22. }
  23. }

我们的GET方式直接在网页后用?和&来书写传递参数:

我们的POST方式只能在下方的body中书写参数:

然后我们需要注意到的是这里的中文同样会出现乱码行为

这次我们选择在ServletContainersInitConfig中处理数据:

  1. // 下述代码基本属于我们创建项目的固定代码
  2. package com.itheima.config;
  3. import org.springframework.web.filter.CharacterEncodingFilter;
  4. import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
  5. import javax.servlet.Filter;
  6. public class ServletContainersInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
  7. protected Class<?>[] getRootConfigClasses() {
  8. return new Class[0]{SpringConfig.class};
  9. }
  10. protected Class<?>[] getServletConfigClasses() {
  11. return new Class[]{SpringMvcConfig.class};
  12. }
  13. protected String[] getServletMappings() {
  14. return new String[]{"/"};
  15. }
  16. //乱码处理
  17. @Override
  18. protected Filter[] getServletFilters() {
  19. // CharacterEncodingFilter 属于处理中文编码的过滤器,我们直接创建即可(一次性操作)
  20. CharacterEncodingFilter filter = new CharacterEncodingFilter();
  21. filter.setEncoding("UTF-8");
  22. return new Filter[]{filter};
  23. }
  24. }

按参数方式

我们按参数来分类主要分为五种:

  • 普通参数
  • POJO类
  • 嵌套式POJO类
  • 数组参数
  • 集合参数

我们下面来一一介绍

普通参数

普通参数:请求参数和形参变量名相同时,自动匹配

  1. package com.itheima.controller;
  2. import com.itheima.domain.User;
  3. import org.springframework.format.annotation.DateTimeFormat;
  4. import org.springframework.stereotype.Controller;
  5. import org.springframework.web.bind.annotation.RequestBody;
  6. import org.springframework.web.bind.annotation.RequestMapping;
  7. import org.springframework.web.bind.annotation.RequestParam;
  8. import org.springframework.web.bind.annotation.ResponseBody;
  9. import java.util.Arrays;
  10. import java.util.Date;
  11. import java.util.List;
  12. //请求参数
  13. @Controller
  14. public class UserController {
  15. //普通参数:请求参数与形参名称对应即可完成参数传递
  16. @RequestMapping("/commonParam")
  17. @ResponseBody
  18. public String commonParam(String name ,int age){
  19. System.out.println("普通参数传递 name ==> "+name);
  20. System.out.println("普通参数传递 age ==> "+age);
  21. return "{'module':'common param'}";
  22. }
  23. }

Postman操作:

这里需要注意:当请求参数名与形参名不同时,使用@RequestParam注解关联请求参数名称与形参名称之间的关系

  1. package com.itheima.controller;
  2. import com.itheima.domain.User;
  3. import org.springframework.format.annotation.DateTimeFormat;
  4. import org.springframework.stereotype.Controller;
  5. import org.springframework.web.bind.annotation.RequestBody;
  6. import org.springframework.web.bind.annotation.RequestMapping;
  7. import org.springframework.web.bind.annotation.RequestParam;
  8. import org.springframework.web.bind.annotation.ResponseBody;
  9. import java.util.Arrays;
  10. import java.util.Date;
  11. import java.util.List;
  12. //请求参数
  13. @Controller
  14. public class UserController {
  15. //普通参数:请求参数名与形参名不同时,使用@RequestParam注解关联请求参数名称与形参名称之间的关系
  16. @RequestMapping("/commonParamDifferentName")
  17. @ResponseBody
  18. public String commonParamDifferentName(@RequestParam("name") String userName , int age){
  19. System.out.println("普通参数传递 userName ==> "+userName);
  20. System.out.println("普通参数传递 age ==> "+age);
  21. return "{'module':'common param different name'}";
  22. }
  23. }

Postman操作:

@RequestParam:绑定请求参数与处理器方法形参间的关系

包含有两个参数

required:是否为必传参数

defaultValue:参数默认值

POJO参数

POJO参数:请求参数名与形参对象属性名相同,定义POJO类型形参即可接收参数

  1. package com.itheima.controller;
  2. import com.itheima.domain.User;
  3. import org.springframework.format.annotation.DateTimeFormat;
  4. import org.springframework.stereotype.Controller;
  5. import org.springframework.web.bind.annotation.RequestBody;
  6. import org.springframework.web.bind.annotation.RequestMapping;
  7. import org.springframework.web.bind.annotation.RequestParam;
  8. import org.springframework.web.bind.annotation.ResponseBody;
  9. import java.util.Arrays;
  10. import java.util.Date;
  11. import java.util.List;
  12. //请求参数
  13. @Controller
  14. public class UserController {
  15. //POJO参数:请求参数与形参对象中的属性对应即可完成参数传递
  16. @RequestMapping("/pojoParam")
  17. @ResponseBody
  18. public String pojoParam(User user){
  19. System.out.println("pojo参数传递 user ==> "+user);
  20. return "{'module':'pojo param'}";
  21. }
  22. }

Postman操作:

嵌套POJO参数

嵌套POJO参数:请求参数名与形参对象属性名相同,按照对象层次结构关系即可接收嵌套POJO属性参数

  1. package com.itheima.controller;
  2. import com.itheima.domain.User;
  3. import org.springframework.format.annotation.DateTimeFormat;
  4. import org.springframework.stereotype.Controller;
  5. import org.springframework.web.bind.annotation.RequestBody;
  6. import org.springframework.web.bind.annotation.RequestMapping;
  7. import org.springframework.web.bind.annotation.RequestParam;
  8. import org.springframework.web.bind.annotation.ResponseBody;
  9. import java.util.Arrays;
  10. import java.util.Date;
  11. import java.util.List;
  12. //请求参数
  13. @Controller
  14. public class UserController {
  15. //嵌套POJO参数:嵌套属性按照层次结构设定名称即可完成参数传递
  16. @RequestMapping("/pojoContainPojoParam")
  17. @ResponseBody
  18. public String pojoContainPojoParam(User user){
  19. System.out.println("pojo嵌套pojo参数传递 user ==> "+user);
  20. return "{'module':'pojo contain pojo param'}";
  21. }
  22. }

Postman操作:

数组参数

数组参数:请求参数名与形参对象属性名相同且请求参数为多个,定义数组类型形参即可接收参数

  1. package com.itheima.controller;
  2. import com.itheima.domain.User;
  3. import org.springframework.format.annotation.DateTimeFormat;
  4. import org.springframework.stereotype.Controller;
  5. import org.springframework.web.bind.annotation.RequestBody;
  6. import org.springframework.web.bind.annotation.RequestMapping;
  7. import org.springframework.web.bind.annotation.RequestParam;
  8. import org.springframework.web.bind.annotation.ResponseBody;
  9. import java.util.Arrays;
  10. import java.util.Date;
  11. import java.util.List;
  12. //请求参数
  13. @Controller
  14. public class UserController {
  15. //数组参数:同名请求参数可以直接映射到对应名称的形参数组对象中
  16. @RequestMapping("/arrayParam")
  17. @ResponseBody
  18. public String arrayParam(String[] likes){
  19. System.out.println("数组参数传递 likes ==> "+ Arrays.toString(likes));
  20. return "{'module':'array param'}";
  21. }
  22. }

Postman操作:

集合保存普通参数

集合保存普通参数:请求参数与形参集合对象名相同且请求参数为多个,@RequestParam绑定参数关系

  1. package com.itheima.controller;
  2. import com.itheima.domain.User;
  3. import org.springframework.format.annotation.DateTimeFormat;
  4. import org.springframework.stereotype.Controller;
  5. import org.springframework.web.bind.annotation.RequestBody;
  6. import org.springframework.web.bind.annotation.RequestMapping;
  7. import org.springframework.web.bind.annotation.RequestParam;
  8. import org.springframework.web.bind.annotation.ResponseBody;
  9. import java.util.Arrays;
  10. import java.util.Date;
  11. import java.util.List;
  12. //请求参数
  13. @Controller
  14. public class UserController {
  15. //集合参数:同名请求参数可以使用@RequestParam注解映射到对应名称的集合对象中作为数据
  16. @RequestMapping("/listParam")
  17. @ResponseBody
  18. public String listParam(@RequestParam List<String> likes){
  19. System.out.println("集合参数传递 likes ==> "+ likes);
  20. return "{'module':'list param'}";
  21. }
  22. }

Postman参数:

按特殊参数方式

我们的特殊参数主要介绍两种:

  • JSON类型
  • 日期类型

我们下面一一介绍

JSON类型

JSON类型是我们Web开发中最常用的类型,所以这一部分算是一个小重点

我们将一一讲解JSON类型传递的步骤:

  1. 导入JSON坐标
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  4. <modelVersion>4.0.0</modelVersion>
  5. <groupId>com.itheima</groupId>
  6. <artifactId>springmvc_04_request_param</artifactId>
  7. <version>1.0-SNAPSHOT</version>
  8. <packaging>war</packaging>
  9. <dependencies>
  10. <dependency>
  11. <groupId>javax.servlet</groupId>
  12. <artifactId>javax.servlet-api</artifactId>
  13. <version>3.1.0</version>
  14. <scope>provided</scope>
  15. </dependency>
  16. <dependency>
  17. <groupId>org.springframework</groupId>
  18. <artifactId>spring-webmvc</artifactId>
  19. <version>5.2.10.RELEASE</version>
  20. </dependency>
  21. <!--JSON坐标--->
  22. <dependency>
  23. <groupId>com.fasterxml.jackson.core</groupId>
  24. <artifactId>jackson-databind</artifactId>
  25. <version>2.9.0</version>
  26. </dependency>
  27. </dependencies>
  28. <build>
  29. <plugins>
  30. <plugin>
  31. <groupId>org.apache.tomcat.maven</groupId>
  32. <artifactId>tomcat7-maven-plugin</artifactId>
  33. <version>2.1</version>
  34. <configuration>
  35. <port>80</port>
  36. <path>/</path>
  37. </configuration>
  38. </plugin>
  39. </plugins>
  40. </build>
  41. </project>
  1. 在SpringMVC配置类中添加JSON类型转换注解
  1. package com.itheima.config;
  2. import org.springframework.context.annotation.ComponentScan;
  3. import org.springframework.context.annotation.Configuration;
  4. import org.springframework.web.filter.CharacterEncodingFilter;
  5. import org.springframework.web.servlet.config.annotation.EnableWebMvc;
  6. import javax.servlet.Filter;
  7. import javax.servlet.annotation.WebFilter;
  8. @Configuration
  9. @ComponentScan("com.itheima.controller")
  10. //开启json数据类型自动转换
  11. @EnableWebMvc
  12. public class SpringMvcConfig {
  13. }
  1. 在Controller中书写相关Web代码(注意:需要使用@RequestBody表示将请求体数据传递给请求参数)
  1. package com.itheima.controller;
  2. import com.itheima.domain.User;
  3. import org.springframework.format.annotation.DateTimeFormat;
  4. import org.springframework.stereotype.Controller;
  5. import org.springframework.web.bind.annotation.RequestBody;
  6. import org.springframework.web.bind.annotation.RequestMapping;
  7. import org.springframework.web.bind.annotation.RequestParam;
  8. import org.springframework.web.bind.annotation.ResponseBody;
  9. import java.util.Arrays;
  10. import java.util.Date;
  11. import java.util.List;
  12. //请求参数
  13. @Controller
  14. public class UserController {
  15. //集合参数:json格式
  16. //1.开启json数据格式的自动转换,在配置类中开启@EnableWebMvc
  17. //2.使用@RequestBody注解将外部传递的json数组数据映射到形参的集合对象中作为数据
  18. @RequestMapping("/listParamForJson")
  19. @ResponseBody
  20. public String listParamForJson(@RequestBody List<String> likes){
  21. System.out.println("list common(json)参数传递 list ==> "+likes);
  22. return "{'module':'list common for json param'}";
  23. }
  24. //POJO参数:json格式
  25. //1.开启json数据格式的自动转换,在配置类中开启@EnableWebMvc
  26. //2.使用@RequestBody注解将外部传递的json数据映射到形参的实体类对象中,要求属性名称一一对应
  27. @RequestMapping("/pojoParamForJson")
  28. @ResponseBody
  29. public String pojoParamForJson(@RequestBody User user){
  30. System.out.println("pojo(json)参数传递 user ==> "+user);
  31. return "{'module':'pojo for json param'}";
  32. }
  33. //集合参数:json格式
  34. //1.开启json数据格式的自动转换,在配置类中开启@EnableWebMvc
  35. //2.使用@RequestBody注解将外部传递的json数组数据映射到形参的保存实体类对象的集合对象中,要求属性名称一一对应
  36. @RequestMapping("/listPojoParamForJson")
  37. @ResponseBody
  38. public String listPojoParamForJson(@RequestBody List<User> list){
  39. System.out.println("list pojo(json)参数传递 list ==> "+list);
  40. return "{'module':'list pojo for json param'}";
  41. }
  42. }

Postman操作:

在上面我们有两个注解需要特别注意一下:

  1. @EnableWebMvc
  • 名称:@EnableWebMvc
  • 类型:配置类注解
  • 位置:SpringMVC配置类定义上方
  • 作用:开启SpringMVC多项辅助功能
  1. @RequestBody
  • 名称:@RequestBody
  • 类型:形参注解
  • 位置:SpringMVC控制器方法形参定义前面
  • 作用:将请求中请求体所包含的数据传递给请求参数,此注解一个处理器方法只能使用一次

@RequestBody和@RequestParam区别

  • 区别

    • @RequestParam用于接收url地址传参,表单传参[application/x-www-form-urlencoded]
    • @RequestBody用于接收JSON数据[application/json]
  • 应用
    • 后期开发中,发送json数据为主,@RequestBody应用较广
    • 如果发送非json格式数据,选用@RequestParam接收请求参数
日期型参数类型

我们的日期类型数据基于系统不同格式也不相同,大致有以下几种:

  • 2022-10-05
  • 2022/10/05
  • 10/05/2022

接收形参时,我们根据不同的日期格式设置不同的接收方式

  1. package com.itheima.controller;
  2. import com.itheima.domain.User;
  3. import org.springframework.format.annotation.DateTimeFormat;
  4. import org.springframework.stereotype.Controller;
  5. import org.springframework.web.bind.annotation.RequestBody;
  6. import org.springframework.web.bind.annotation.RequestMapping;
  7. import org.springframework.web.bind.annotation.RequestParam;
  8. import org.springframework.web.bind.annotation.ResponseBody;
  9. import java.util.Arrays;
  10. import java.util.Date;
  11. import java.util.List;
  12. //请求参数
  13. @Controller
  14. public class UserController {
  15. //日期参数
  16. //使用@DateTimeFormat注解设置日期类型数据格式,默认格式yyyy/MM/dd
  17. @RequestMapping("/dataParam")
  18. @ResponseBody
  19. public String dataParam(Date date,
  20. @DateTimeFormat(pattern="yyyy-MM-dd") Date date1,
  21. @DateTimeFormat(pattern="yyyy/MM/dd HH:mm:ss") Date date2){
  22. System.out.println("参数传递 date ==> "+date);
  23. System.out.println("参数传递 date1(yyyy-MM-dd) ==> "+date1);
  24. System.out.println("参数传递 date2(yyyy/MM/dd HH:mm:ss) ==> "+date2);
  25. return "{'module':'data param'}";
  26. }
  27. }
  28. /*
  29. 名称:@DateTimeFormat
  30. 类型:形参注解
  31. 位置:SpringMVC控制器方法前
  32. 作用:设定日期时间型数据格式
  33. 属性:pattern:日期时间格式字符串
  34. */

Postman操作:

这里我们简单介绍一下@DateTimeFormat的转换原理Converter接口:

  1. public interface Converter<S,T>{
  2. @Nullable
  3. T convert(S var1)
  4. }

Converter接口属于顶层接口,由它为起源创建了许多相关的接口与类用于各种转化:

  • 请求参数年龄数据(String->Integer)
  • 日期格式转发(String->Date)

@EnableWebMvc功能之一:根据类型匹配对应的类型转换器

设置响应

在了解请求的相关知识之后,我们回到Controller代码中学习一下响应

跳转响应

在正常情况下,我们的响应给出的是当前项目的文档,相当于页面的跳转效应:

  1. package com.itheima.controller;
  2. import com.itheima.domain.User;
  3. import org.springframework.format.annotation.DateTimeFormat;
  4. import org.springframework.stereotype.Controller;
  5. import org.springframework.web.bind.annotation.RequestMapping;
  6. import org.springframework.web.bind.annotation.ResponseBody;
  7. import java.util.ArrayList;
  8. import java.util.Date;
  9. import java.util.List;
  10. @Controller
  11. public class UserController {
  12. //响应页面/跳转页面
  13. //返回值为String类型,设置返回值为页面名称,即可实现页面跳转
  14. @RequestMapping("/toJumpPage")
  15. public String toJumpPage(){
  16. System.out.println("跳转页面");
  17. return "page.jsp";
  18. }
  19. }

信息响应

如果我们希望得到一些信息响应,就需要采用注解解释:

  1. package com.itheima.controller;
  2. import com.itheima.domain.User;
  3. import org.springframework.format.annotation.DateTimeFormat;
  4. import org.springframework.stereotype.Controller;
  5. import org.springframework.web.bind.annotation.RequestMapping;
  6. import org.springframework.web.bind.annotation.ResponseBody;
  7. import java.util.ArrayList;
  8. import java.util.Date;
  9. import java.util.List;
  10. @Controller
  11. public class UserController {
  12. //响应文本数据
  13. //返回值为String类型,设置返回值为任意字符串信息,即可实现返回指定字符串信息,需要依赖@ResponseBody注解
  14. @RequestMapping("/toText")
  15. @ResponseBody
  16. public String toText(){
  17. System.out.println("返回纯文本数据");
  18. return "response text";
  19. }
  20. //响应POJO对象
  21. //返回值为实体类对象,设置返回值为实体类类型,即可实现返回对应对象的json数据,需要依赖@ResponseBody注解和@EnableWebMvc注解
  22. @RequestMapping("/toJsonPOJO")
  23. @ResponseBody
  24. public User toJsonPOJO(){
  25. System.out.println("返回json对象数据");
  26. User user = new User();
  27. user.setName("itcast");
  28. user.setAge(15);
  29. return user;
  30. }
  31. //响应POJO集合对象
  32. //返回值为集合对象,设置返回值为集合类型,即可实现返回对应集合的json数组数据,需要依赖@ResponseBody注解和@EnableWebMvc注解
  33. @RequestMapping("/toJsonList")
  34. @ResponseBody
  35. public List<User> toJsonList(){
  36. System.out.println("返回json集合数据");
  37. User user1 = new User();
  38. user1.setName("传智播客");
  39. user1.setAge(15);
  40. User user2 = new User();
  41. user2.setName("黑马程序员");
  42. user2.setAge(12);
  43. List<User> userList = new ArrayList<User>();
  44. userList.add(user1);
  45. userList.add(user2);
  46. return userList;
  47. }
  48. }
  49. /*
  50. 名称:@ResponseBody
  51. 类型:方法注解
  52. 位置:SpringMVC控制器方法定义上方
  53. 作用:设置当前控制器返回值作为响应体
  54. */

当我们使用Postman访问该链接时就会给出对应反馈,这里就不做演示了

REST风格

首先我们来简单介绍一下REST:

  • REST(Representational State Transfer),表现形式状态转换

我们给出正常风格和REST风格两种书写形式,我们可以明显看到REST的内容做出大规模的省略:

REST风格优点:

  • 书写简化
  • 隐藏资源的访问行为,无法通过地址得知对资源的操作

REST风格简介

我们来对REST风格做出简单解释:

  • REST风格是采用访问资源的行为动作来区别对资源进行了何种操作

我们给出五种常见行为动作:

我们通常将根据REST风格进行的访问称为RESTful

上述行为是约定方式,约定不是规范,是可以打破的,所以称为REST风格,而不是REST规范

描述模块的名称通常使用负数,也就是加s的格式描述,表示此类,而非单个资源

RESTful入门案例

从本质上而言,REST只是一种规范形式,我们对于REST的风格修改仅针对于Controller

我们下面将逐步进行RESTful的修改:

  1. 设置http请求动作
  1. package com.itheima.controller;
  2. import com.itheima.domain.Book;
  3. import org.springframework.stereotype.Controller;
  4. import org.springframework.web.bind.annotation.*;
  5. @Controller
  6. public class BookController {
  7. // RequestMapping中包含value和method两种属性
  8. // value:访问路径
  9. // method:访问方法
  10. @RequestMapping(value = "/users",method = Request.POST)
  11. @RequestBody
  12. public String save(@RequestBody User user){
  13. System.out.println("user save" + user);
  14. return "{'module':'user save'}"
  15. }
  16. }
  17. /*
  18. 名称:@RequestMapping
  19. 类型:方法注解
  20. 位置:SpringMVC控制器方法定义上方
  21. 作用:设置当前控制器方法请求访问路径
  22. 属性:value访问路径,method请求动作
  23. */
  1. 设置请求参数(路径变量)
  1. package com.itheima.controller;
  2. import com.itheima.domain.Book;
  3. import org.springframework.stereotype.Controller;
  4. import org.springframework.web.bind.annotation.*;
  5. @Controller
  6. public class BookController {
  7. // 首先针对我们所需参数给出@PathVariable注解,并在访问路径中采用{}占位表示所传数据
  8. // 简单来说就是,系统根据请求路径,得到所需数据,再带入到方法中
  9. @RequestMapping(value = "/users/{id}" ,method = RequestMethod.DELETE)
  10. @RequestBody
  11. public String delete(@PathVariable Integer id){
  12. System.out.println("book delete..." + id);
  13. return "{'module':'book delete'}";
  14. }
  15. }
  16. /*
  17. 名称:@PathVariable
  18. 类型:形参注解
  19. 位置:SpringMVC控制器方法形参定义前面
  20. 作用:绑定路径参数与处理器方法形参间的关系,要求路径参数名与形参名一一对应
  21. */

下面我们给出所有情况案例:

  1. package com.itheima.controller;
  2. import com.itheima.domain.User;
  3. import org.springframework.stereotype.Controller;
  4. import org.springframework.web.bind.annotation.*;
  5. @Controller
  6. public class UserController {
  7. //设置当前请求方法为POST,表示REST风格中的添加操作
  8. @RequestMapping(value = "/users",method = RequestMethod.POST)
  9. @ResponseBody
  10. public String save(){
  11. System.out.println("user save...");
  12. return "{'module':'user save'}";
  13. }
  14. //设置当前请求方法为DELETE,表示REST风格中的删除操作
  15. //@PathVariable注解用于设置路径变量(路径参数),要求路径上设置对应的占位符,并且占位符名称与方法形参名称相同
  16. @RequestMapping(value = "/users/{id}",method = RequestMethod.DELETE)
  17. @ResponseBody
  18. public String delete(@PathVariable Integer id){
  19. System.out.println("user delete..." + id);
  20. return "{'module':'user delete'}";
  21. }
  22. //设置当前请求方法为PUT,表示REST风格中的修改操作
  23. @RequestMapping(value = "/users",method = RequestMethod.PUT)
  24. @ResponseBody
  25. public String update(@RequestBody User user){
  26. System.out.println("user update..."+user);
  27. return "{'module':'user update'}";
  28. }
  29. //设置当前请求方法为GET,表示REST风格中的查询操作
  30. //@PathVariable注解用于设置路径变量(路径参数),要求路径上设置对应的占位符,并且占位符名称与方法形参名称相同
  31. @RequestMapping(value = "/users/{id}" ,method = RequestMethod.GET)
  32. @ResponseBody
  33. public String getById(@PathVariable Integer id){
  34. System.out.println("user getById..."+id);
  35. return "{'module':'user getById'}";
  36. }
  37. //设置当前请求方法为GET,表示REST风格中的查询操作
  38. @RequestMapping(value = "/users",method = RequestMethod.GET)
  39. @ResponseBody
  40. public String getAll(){
  41. System.out.println("user getAll...");
  42. return "{'module':'user getAll'}";
  43. }
  44. }
  45. /*
  46. 下述为原有代码:
  47. @RequestMapping
  48. @ResponseBody
  49. public String delete(){
  50. System.out.println("user delete...");
  51. return "{'module':'user delete'}";
  52. }
  53. @RequestMapping
  54. @ResponseBody
  55. public String update(){
  56. System.out.println("user update...");
  57. return "{'module':'user update'}";
  58. }
  59. @RequestMapping
  60. @ResponseBody
  61. public String getById(){
  62. System.out.println("user getById...");
  63. return "{'module':'user getById'}";
  64. }
  65. @RequestMapping
  66. @ResponseBody
  67. public String getAll(){
  68. System.out.println("user getAll...");
  69. return "{'module':'user getAll'}";
  70. }
  71. */

我们在这里给出@RequestBody,@RequestParam,@PathVariable区别

区别:

  • @RequestParam用于接收url地址传参或表单传参
  • @RequestBody用于接收json数据
  • @PathVariable用于接收路径参数,使用{参数名称}描述路径参数

应用:

  • 后期开发中,发送请求参数超过1个时,以json格式为主,@RequestBody应用较广
  • 如果发送非json格式数据,选用@RequestParam接受请求参数
  • 采用RESTful进行开发,当参数数量较少时,如1个,可以采用@PathVariable接收请求路径变量,常用来传递id值

REST快速开发

我们在上一小节中会发现有许多重复性的代码:

  1. // 每次都填写value,method导致代码繁冗
  2. // 包括每次填写ResponseBody使代码繁冗
  3. @RequestMapping(value = "/users",method = RequestMethod.GET)
  4. @ResponseBody

所以我们可以采用一些小技巧来简化代码:

  • 将前缀地址和相关注解放于类中:
  1. package com.itheima.controller;
  2. import com.itheima.domain.Book;
  3. import org.springframework.stereotype.Controller;
  4. import org.springframework.web.bind.annotation.*;
  5. //@Controller
  6. //@ResponseBody
  7. @RestController
  8. @RequestMapping("/books")
  9. public class BookController {
  10. }
  11. /*
  12. 正常情况下,我们的类本身具有@Controller,并且为了省略类中的@ResponseBody而直接标注在类头
  13. 但Spring提供了一种新的注解@RestController,相当于@Controller和@ResponseBody的结合,我们只需要书写这一个注解即可
  14. 名称:@RestController
  15. 类型:类注解
  16. 位置:基于SpringMVC的RESTful开发控制器类定义上方
  17. 作用:设置当前控制器为RESTful风格,等同于@Controller与@ResponseBody两个注解组合功能
  18. */
  • 采用新的地址注解代替老注解:
  1. package com.itheima.controller;
  2. import com.itheima.domain.Book;
  3. import org.springframework.stereotype.Controller;
  4. import org.springframework.web.bind.annotation.*;
  5. @RestController
  6. @RequestMapping("/books")
  7. public class BookController {
  8. //@RequestMapping( method = RequestMethod.POST)
  9. //使用@PostMapping简化Post请求方法对应的映射配置
  10. @PostMapping
  11. public String save(@RequestBody Book book){
  12. System.out.println("book save..." + book);
  13. return "{'module':'book save'}";
  14. }
  15. //@RequestMapping(value = "/{id}" ,method = RequestMethod.DELETE)
  16. //使用@DeleteMapping简化DELETE请求方法对应的映射配置
  17. @DeleteMapping("/{id}")
  18. public String delete(@PathVariable Integer id){
  19. System.out.println("book delete..." + id);
  20. return "{'module':'book delete'}";
  21. }
  22. //@RequestMapping(method = RequestMethod.PUT)
  23. //使用@PutMapping简化Put请求方法对应的映射配置
  24. @PutMapping
  25. public String update(@RequestBody Book book){
  26. System.out.println("book update..."+book);
  27. return "{'module':'book update'}";
  28. }
  29. //@RequestMapping(value = "/{id}" ,method = RequestMethod.GET)
  30. //使用@GetMapping简化GET请求方法对应的映射配置
  31. @GetMapping("/{id}")
  32. public String getById(@PathVariable Integer id){
  33. System.out.println("book getById..."+id);
  34. return "{'module':'book getById'}";
  35. }
  36. //@RequestMapping(method = RequestMethod.GET)
  37. //使用@GetMapping简化GET请求方法对应的映射配置
  38. @GetMapping
  39. public String getAll(){
  40. System.out.println("book getAll...");
  41. return "{'module':'book getAll'}";
  42. }
  43. }
  44. /*
  45. 名称:@GetMapping @PostMapping @PutMapping @DeleteMapping
  46. 类型:方法注解
  47. 位置:基于SpringMVC的RESTful开发控制器方法定义上方
  48. 作用:设置当前控制器方法请求访问路径与请求动作,每种对应一个请求动作,例如@GetMapping对应GET请求
  49. 参数:value请求访问路径
  50. */

结束语

好的,关于SpringMVC的内容就介绍到这里,希望能为你带来帮助!

附录

该文章属于学习内容,具体参考B站黑马程序员李老师的SSM框架课程

这里附上链接:SpringMVC-01-SpringMVC简介_哔哩哔哩_bilibili

一篇文章带你掌握主流服务层框架——SpringMVC的更多相关文章

  1. 一篇文章带你掌握主流基础框架——Spring

    一篇文章带你掌握主流基础框架--Spring 这篇文章中我们将会介绍Spring的框架以及本体内容,包括核心容器,注解开发,AOP以及事务等内容 那么简单说明一下Spring的必要性: Spring技 ...

  2. 一篇文章带你掌握主流办公框架——SpringBoot

    一篇文章带你掌握主流办公框架--SpringBoot 在之前的文章中我们已经学习了SSM的全部内容以及相关整合 SSM是Spring的产品,主要用来简化开发,但我们现在所介绍的这款框架--Spring ...

  3. 一篇文章带你掌握主流数据库框架——MyBatis

    一篇文章带你掌握主流数据库框架--MyBatis MyBatis 是一款优秀的持久层框架,它支持自定义 SQL.存储过程以及高级映射. 在之前的文章中我们学习了MYSQL和JDBC,但是这些东西远远不 ...

  4. 一篇文章带你掌握MyBatis简化框架——MyBatisPlus

    一篇文章带你掌握MyBatis简化框架--MyBatisPlus 我们在前面的文章中已经学习了目前开发所需的主流框架 类似于我们所学习的SpringBoot框架用于简化Spring开发,我们的国人大大 ...

  5. 一篇文章带你了解网页框架——Vue简单入门

    一篇文章带你了解网页框架--Vue简单入门 这篇文章将会介绍我们前端入门级别的框架--Vue的简单使用 如果你以后想从事后端程序员,又想要稍微了解前端框架知识,那么这篇文章或许可以给你带来帮助 温馨提 ...

  6. MYSQL(基本篇)——一篇文章带你走进MYSQL的奇妙世界

    MYSQL(基本篇)--一篇文章带你走进MYSQL的奇妙世界 MYSQL算是我们程序员必不可少的一份求职工具了 无论在什么岗位,我们都可以看到应聘要求上所书写的"精通MYSQL等数据库及优化 ...

  7. MYSQL(进阶篇)——一篇文章带你深入掌握MYSQL

    MYSQL(进阶篇)--一篇文章带你深入掌握MYSQL 我们在上篇文章中已经学习了MYSQL的基本语法和概念 在这篇文章中我们将讲解底层结构和一些新的语法帮助你更好的运用MYSQL 温馨提醒:该文章大 ...

  8. 一篇文章带你了解热门版本控制系统——Git

    一篇文章带你了解热门版本控制系统--Git 这篇文章会介绍到关于版本控制的相关知识以及版本控制神器Git 我们可能在生活中经常会使用GitHub网页去查询一些开源的资源或者项目,GitHub就是基于G ...

  9. 一篇文章带你了解服务器操作系统——Linux简单入门

    一篇文章带你了解服务器操作系统--Linux简单入门 Linux作为服务器的常用操作系统,身为工作人员自然是要有所了解的 在本篇中我们会简单介绍Linux的特点,安装,相关指令使用以及内部程序的安装等 ...

随机推荐

  1. 西文字符与中文GBK编码的区别

    一般来讲二者读取的时候西文字符的数值是正,而中文字符的数值是负的,此时读取的是中文字符的前一半,需要再读取一个char类型的数据,在大多数运行环境下这个规则都是用. ps:转自算法竞赛的笔记,要注意在 ...

  2. 【人工智能】【Python】Matplotlib基础

    Maplotlib 本文档由萌狼蓝天写于2022年7月24日 目录 Maplotlib (一)Matplotlib三层结构 (二)画布创建.图像绘制.图像显示 (三)图像画布设置.图像保存 (四)自定 ...

  3. redis集群的三种方式

    Redis三种集群方式:主从复制,哨兵模式,Cluster集群. 主从复制 基本原理 当新建立一个从服务器时,从服务器将向主服务器发送SYNC命令,接收到SYNC命令后的主服务器会进行一次BGSAVE ...

  4. DQL分组查询和DQL分页查询

    分组查询: 1.语法:group by 分组字段: 2.注意: 分组之后查询的字符按:分组字段.聚合函数 where 和having 的区别 where再分组前进行限定,如果不满足条件则不参与分组.h ...

  5. linux学习随笔3之linux安全

    1.history显示时间,用户和命令 vim /etc/profile export HISTTIMEFORMAT=" %F %T `who -u am i 2>/dev/null| ...

  6. YII场景

    YII在模型中定义场景后 public function scenarios(){//场景 return [ 'sco1'=>['aid','uphone'], 'sco2'=>['aid ...

  7. 常见SQL及备注

  8. redis安装与连接

    安装(centos7): yum install redis 启动与停止: systemctl start redis. service systemctl stop redis.service 修改 ...

  9. Luogu1655 小朋友的球 (组合数学,第二类斯特林数,高精)

    我bingoyes再高精用STL就饿死,死外边! string真的爽... 斯特林数模板题:\(S(n,m) = S(n-1,m-1)+S(n-1,m)*n\) #include <iostre ...

  10. Luogu2251 质量检测 (ST表)

    我怎么开始划水了... #include <iostream> #include <cstdio> #include <cstring> #include < ...