SpringMVC

  • SpringMVC简介
  • 请求与响应
  • REST风格
  • SSM整合(注解版)
  • 拦截器
  1. # 学习目标
  2. 1. 掌握基于SpringMVC获取请求参数与响应json数据操作
  3. 2. 熟练应用基于REST风格的请求路径设置与参数传递
  4. 3. 能够根据实际业务建立前后端开发通信协议并进行实现
  5. 4. 基于SSM整合技术开发任意业务模块功能

1. SpringMVC简介

1.1 SpringMVC概述

1.1.1 请求响应模式演进过程

三层架构

  • 表现层:负责数据展示,跟前端打交道(web,view,controller)
  • 业务层:负责业务处理(service)
  • 数据层:负责数据操作,跟数据库打交道(dao)

day04_SpringMVC - 图1

MVC(Model View Controller)

  • Model(模型):数据模型,用于封装数据 (bean)

    • eg:用户登录功能:前端输入用户名和密码——》传到后台——》控制器(servlet|controller)接收——》将用户名和密码封装到user对象中,而这个user对象就可以人为是一个Model
    • eg:根据用户id查询用户信息,后台向前端放回一个User对象,这个查询得到的user对象也是一个Model
    • 总之,model就是前端与后端在进行数据交互时产生的数据对象;
  • View(视图):页面视图,用于展示数据(一切展示数据的方式:html\text\json\xml等)
  • Controller(控制器):处理用户交互的调度器(servlet),用于根据用户需求处理程序逻辑
  • 总之,MVC架构是对三层架构中web层的再细粒度划分;

请求响应模式演进过程

web阶段的开发

说明:后端通过web控制器(servlet)直接将视图资源(jsp+数据)响应给前端浏览器,控制器、视图资源和展示的数据是耦合到一块的,分层不明显;

弊端:页面、数据和控制器耦合到一块,代码的复用性很差,可维护性非常低;

day04_SpringMVC - 图2

同步请求场景下的springMVC开发

说明:mvc架构则将web层的控制器(servlet|controller)、视图资源、展示的数据model解耦分层管理,方便维护;

day04_SpringMVC - 图3

异步请求场景下的springMVC开发

说明:前后端直接通过json进行异步交互,格式统一,维护性较好;

  1. 说白了,就是将mvc架构中view视图层提取出来独立作为前端资源部署,然后后端控制层(controller)将model转化成json数据与前端进行交互;

day04_SpringMVC - 图4

1.1.2 SpringMVC概述

  1. 1. SpringMVC是一种基于Java实现MVC模型的轻量级Web框架
  2. 1). 底层基于Spring
  3. 2). 封装了web三大组件(Servlet,Filter,Listener)
  4. 2. 优点
  5. 1). 使用简单,开发便捷(相比于Servlet
  6. 2). 灵活性强

1.2 入门案例

1.2.1 入门案例编写

day04_SpringMVC - 图5

①: 导入SpringMVC坐标与Servlet坐标

  1. <dependency>
  2. <groupId>javax.servlet</groupId>
  3. <artifactId>javax.servlet-api</artifactId>
  4. <version>3.1.0</version>
  5. <scope>provided</scope>
  6. </dependency>
  7. <dependency>
  8. <groupId>org.springframework</groupId>
  9. <artifactId>spring-webmvc</artifactId>
  10. <version>5.2.10.RELEASE</version>
  11. </dependency>

②:初始化SpringMVC环境(同Spring环境)

  1. //springmvc配置类,本质上还是一个spring配置类
  2. @Configuration
  3. @ComponentScan("com.itheima.controller")
  4. public class SpringMvcConfig {
  5. }

③:创建SpringMVC控制器类(等同于Servlet功能)

  1. //定义表现层控制器bean
  2. @Controller
  3. public class UserController {
  4. //设置映射路径为/save,即外部访问路径
  5. @RequestMapping("/save")
  6. //设置当前操作返回结果为字符串
  7. @ResponseBody
  8. public String save(){
  9. System.out.println("user save ...");
  10. return "hello";
  11. }
  12. }

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

  1. //AbstractDispatcherServletInitializer类是SpringMVC提供的快速初始化Web3.0容器的抽象类
  2. //web容器配置类
  3. public class ServletContainersInitConfig extends AbstractDispatcherServletInitializer {
  4. //加载springmvc配置类,产生springmvc容器(本质还是spring容器)
  5. protected WebApplicationContext createServletApplicationContext() {
  6. //初始化WebApplicationContext对象
  7. AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
  8. //加载指定配置类
  9. ctx.register(SpringMvcConfig.class);
  10. return ctx;
  11. }
  12. //设置由springmvc控制器处理的请求映射路径
  13. protected String[] getServletMappings() {
  14. return new String[]{"/"};
  15. }
  16. //加载spring配置类
  17. protected WebApplicationContext createRootApplicationContext() {
  18. return null;
  19. }
  20. }

⑤:将项目部署到tomcat,并 使用浏览器测试请求

http://localhost:8080/save

day04_SpringMVC - 图6

1.2.2 核心API

  1. # @Controller
  2. 1. 类型:**类注解**
  3. 2. 位置:SpringMVC控制器类定义上方
  4. 3. 作用:设定SpringMVC的核心控制器bean
  5. 4. 范例:
  6. @Controller
  7. public class UserController {
  8. }
  1. # @RequestMapping
  2. 1. 类型:方法注解
  3. 2. 位置:SpringMVC控制器方法定义上方
  4. 3. 作用:设置当前控制器方法请求访问路径
  5. 说白了就是建立请求路径与处理器方法之间的映射关系
  6. 4. 范例:
  7. @RequestMapping("/save")
  8. public void save(){
  9. System.out.println("user save ...");
  10. }
  1. # @ResponseBody
  2. 1. 类型:方法注解
  3. 2. 位置:SpringMVC控制器方法定义上方
  4. 3. 作用:设置当前控制器方法响应体内容为当前返回值,无需解析
  5. 说白了,就是将方法返回值序列化成字符串给前端返回;
  6. 4. 范例:
  7. @RequestMapping("/save")
  8. @ResponseBody
  9. public String save(){
  10. System.out.println("user save ...");
  11. return "hello";
  12. }

1.3 入门案例工作流程分析

SPI:service provider interface :服务提供接口

  1. 大白话:官方给开发者提供一个公共的接口标准(比如:jdbc提供Driver接口标准)
  2. 然后各个实现方法实现这个接口,然后将指向放在资源包下META-INF/services下,
  3. 文件名称就是这个公共的接口名称,而文件的内容就是该接口的实现;
  4. 这样,我们只需遵循这个标准,实现方会自动加载这个文件下的实现类,做具体的操作;
  5. 类似于快递柜,官方安装快递柜,邮递员只需遵循快递柜的使用规范,将快递正确放入,我们就是可以按照自己的方式取获取快速;
  1. # 启动服务器初始化过程
  2. 0. tomcat -> ServletContainersInitConfig -> SpringMvcConfig -> UserController
  3. 1. tomcat的启动执时,根据SPI机制加载ServletContainersInitConfig
  4. 1). spring-web.jar下有META-INF/services/javax.servlet.ServletContainerInitializer文件
  5. 2). 此文件中配置实现类 org.springframework.web.SpringServletContainerInitializer
  6. 3). 此类会被tomcat所加载(SPI机制),此类上的有个配置@HandlesTypes({WebApplicationInitializer.class})
  7. 4). 此接口WebApplicationInitializer的所有实现类都会被加载封装到set集合中,通过onStartup方法传入;
  8. (看SpringServletContainerInitializeronStartup)
  9. 5). 而我们入门案例中的ServletContainersInitConfig类就是WebApplicationInitializer实现类,所以也会被运行
  10. 2. ServletContainersInitConfig类的方法会被运行
  11. 1). createServletApplicationContext方法运行,加载springmvc配置类
  12. 2). getServletMappings方法运行, DispatcherServlet类设置访问路径为/ (表示拦截所有)
  13. 3. SpringMvcConfig类配置的注解生效
  14. 1). @ComponentScan("com.itheima.controller")
  15. 2). springmvc底层开始扫描 com.itheima.controller
  16. 4. UserController类生效
  17. 1). @Controller
  18. 表示此bean会添加到springmvcioc容器
  19. 2). @RequestMapping("/save")
  20. 设置save方法的访问路径为 /save
  21. 3). @ResponseBody
  22. 方法的的返回值String将会通过响应体返回给前端
  23. 总之,springmvc通过spi机制调用 SpringServletContainerInitializer中的onstart方法来完成IOC容器以及核心调度器初始化的操作;
  24. # 问题:
  25. 1. 入门案例是一个web项目,为何不写web.xml文件?
  26. SPI机制: ServletContainerInitializer
  27. 2. 入门案例为何不写Servlet?
  28. springMVC底层封装了DispatcherServlet,它拦截所有请求,然后分发给Controller.
  1. # 单次请求过程
  2. 0. 浏览器(前端) -> (后端)tomcat -> DispatcherServlet -> UserController.save
  3. 1. 前端发送请求 http://localhost:8080/save
  4. 2. http://localhost:8080会找到tomcat(web容器-》servlet容器)
  5. 3. tomcat接收到请求,发现spingmvc中有个DispatcherServlet的拦截路径为/,所以就将请求交给DispatcherServlet,service方法会运行
  6. 4. DispatcherServlet会找到/save对应的控制器方法UserController.save方法,然后调用此方法
  7. 5. UserController.save方法运行之后,有String类型的返回值hello,通过响应体返回给前端

ServletContainersInitConfig的常用写法

  1. public class ServletContainersInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
  2. //加载springmvc配置的
  3. protected Class<?>[] getServletConfigClasses() {
  4. return new Class[]{SpringMvcConfig.class};
  5. }
  6. //设置由springmvc控制器处理的请求映射路径
  7. protected String[] getServletMappings() {
  8. return new String[]{"/"};
  9. }
  10. //加载spring配置类
  11. protected Class<?>[] getRootConfigClasses() {
  12. return new Class[0];
  13. }
  14. }

1.4 PostMan

1.4.1 Postman简介

  • Postman是一款功能强大的网页调试与发送网页HTTP请求的Chrome插件
    测试工具

  • 作用:常用于进行接口测试

  • 特征: 简单, 实用,美观, 大方

1.4.2 Postman基本使用

  • 注册登录 (联网)
  • 创建工作空间/进入工作空间
  • 发起请求测试结果

day04_SpringMVC - 图7

2. RequestMapping注解

作用: RequestMapping 注解,用于建立请求路径与方法的对应关系。

2.1 编写位置

  1. # 编写位置:
  2. 1. 类上:
  3. 窄化路径,访问此类中的方法时,必须加上类上的路径
  4. 2. 方法:
  5. 建立路径与方法的对应关系

示例代码

http://localhost:8080/user/save

http://localhost:8080/user/delete

  1. @Controller
  2. //类上方配置的请求映射与方法上面配置的请求映射连接在一起,形成完整的请求映射路径
  3. @RequestMapping("/user")
  4. public class UserController {
  5. //请求路径映射
  6. @RequestMapping("/save")
  7. @ResponseBody
  8. public String save(){
  9. System.out.println("user save ...");
  10. return "hello";
  11. }
  12. //请求路径映射
  13. @RequestMapping("/delete")
  14. @ResponseBody
  15. public String delete(){
  16. System.out.println("user delete ...");
  17. return "hello";
  18. }
  19. }

2.2 常用属性

  1. # @RequestMapping注解常用属性
  2. 1. value或者path: 用来指定虚拟路径,value=可以省略
  3. 2. method: 用来限定请求的方式 (restful风格)
  4. 1). 不写,默认什么请求方式都可以
  5. 2). 写了,指定了请求方式,如果不匹配就会响应405状态码(错误)

示例代码:

  1. @Controller
  2. @RequestMapping("/role")
  3. public class RoleController {
  4. @RequestMapping(value = "/save",
  5. method = RequestMethod.GET)
  6. @ResponseBody
  7. public String save(){
  8. System.out.println("RoleController save...");
  9. return "hello";
  10. }
  11. @RequestMapping(value = "/delete",
  12. method = RequestMethod.POST)
  13. @ResponseBody
  14. public String delete(){
  15. System.out.println("RoleController delete...");
  16. return "hello";
  17. }
  18. }

3. 请求 (重点)

  1. # SpringMVC的请求处理可以分为两大类:
  2. 这里说的同步请求和异步请求指的是前端
  3. 1. 同步请求
  4. 0). 特点: 同步请求的响应内容会刷新整个网页
  5. 1). url格式的请求参数
  6. 2). 响应: 请求转发
  7. 2. 异步请求 (主流!!!)
  8. 0). 特点: 响应内容只会让网页局部刷新
  9. ajax/json (封装库,框架 axios/vue...)
  10. 1). 请求参数
  11. url格式 name=value&name=value...
  12. json格式
  13. 2). 响应
  14. 字符串
  15. json格式
  16. # SpringMvc对请求和响应进行了封装
  17. 1. 我们的控制器方法可以接收请求参数
  18. 2. 如果请求携带以下类型的数据,SpringMVC会自动帮我们接收,并且解析之后传递给方法进行使用
  19. 3. 使用方式: 直接定义方法形参
  20. 4. 注意: 方法上的形参名称必须要和请求参数名称保持一致
  21. 1).基本数据类型和string
  22. 2).pojo类型
  23. 3).数组类型
  24. 4).集合类型

3.1 获取url格式的请求参数

  1. # url格式参数常见类型
  2. 1. 基本数据类型和string
  3. 2. pojo类型
  4. 3. 数组类型
  5. 4. 集合类型

3.1.1 核心代码

导入素材中 springmvc_03_request_param

  1. @Controller
  2. public class UserController {
  3. //普通参数:请求参数与形参名称对应即可完成参数传递
  4. @RequestMapping("/commonParam")
  5. @ResponseBody
  6. public String commonParam(String name ,int age){
  7. System.out.println("普通参数传递 name ==> "+name);
  8. System.out.println("普通参数传递 age ==> "+age);
  9. return "hello";
  10. }
  11. //POJO参数:请求参数与形参对象中的属性对应即可完成参数传递
  12. @RequestMapping("/pojoParam")
  13. @ResponseBody
  14. public String pojoParam(User user){
  15. System.out.println("pojo参数传递 user ==> "+user);
  16. return "hello";
  17. }
  18. //嵌套POJO参数:嵌套属性按照层次结构设定名称即可完成参数传递
  19. @RequestMapping("/pojoContainPojoParam")
  20. @ResponseBody
  21. public String pojoContainPojoParam(User user){
  22. System.out.println("pojo嵌套pojo参数传递 user ==> "+user);
  23. return "hello";
  24. }
  25. //数组参数:同名请求参数可以直接映射到对应名称的形参数组对象中
  26. @RequestMapping("/arrayParam")
  27. @ResponseBody
  28. public String arrayParam(String[] likes){
  29. System.out.println("数组参数传递 likes ==> "+ Arrays.toString(likes));
  30. return "hello";
  31. }
  32. //集合参数:同名请求参数可以使用@RequestParam注解映射到对应名称的集合对象中作为数据
  33. @RequestMapping("/listParam")
  34. @ResponseBody
  35. public String listParam(@RequestParam List<String> likes){
  36. System.out.println("集合参数传递 likes ==> "+ likes);
  37. return "hello";
  38. }
  39. }

3.1.2 Postman发送url格式参数

day04_SpringMVC - 图8

day04_SpringMVC - 图9

day04_SpringMVC - 图10

day04_SpringMVC - 图11

day04_SpringMVC - 图12

day04_SpringMVC - 图13

3.2 获取json格式的请求参数

  1. # json格式数据
  2. 1. 对象 { }
  3. 2. 数组 [ ]
  4. # json格式请求参数常见类型
  5. 1. json数组
  6. String [] / int[]
  7. ["a","b","c"]
  8. 2. json对象(POJO
  9. User
  10. {"name":"zs","age" : 18}
  11. 3. json数组(POJO
  12. List<User>
  13. [{"name":"zs","age" : 18},{"name":"ls","age":19}]
  14. # java中的json转换工具
  15. 1. fastJson ( alibaba )
  16. 1). json格式字符串变成 pojo对象
  17. 2). pojo对象变成json格式字符串
  18. 2. JackSon (springMVC底层使用)
  19. 3. gson
  20. # web阶段封装的一个工具类 BaseController
  21. 1. 接收json格式的请求参数 变成 pojo
  22. 2. pojo的响应数据 变成 json格式字符串

3.2.1 使用步骤

①:添加json数据转换相关坐标

  1. <dependency>
  2. <groupId>com.fasterxml.jackson.core</groupId>
  3. <artifactId>jackson-databind</artifactId>
  4. <version>2.9.0</version>
  5. </dependency>

②:设置发送json数据(请求body中添加json数据)

day04_SpringMVC - 图14

③:开启自动转换json数据的支持

  1. @Configuration
  2. @ComponentScan("com.itheima.controller")
  3. //开启json数据类型自动转换
  4. //@EnableWebMvc注解功能强大,该注解整合了多个功能,此处仅使用其中一部分功能,即json数据进行自动类型转换
  5. @EnableWebMvc
  6. public class SpringMvcConfig {
  7. }

④:设置接收json数据

  1. @RequestMapping("/listPojoParamForJson")
  2. @ResponseBody
  3. public String listPojoParamForJson(@RequestBody List<User> list){
  4. System.out.println("list pojo(json)参数传递 list ==> "+list);
  5. return "{'module':'list pojo for json param'}";
  6. }

核心代码

  1. //集合参数:json格式
  2. //1.开启json数据格式的自动转换,在配置类中开启@EnableWebMvc
  3. //2.使用@RequestBody注解将外部传递的json数组数据映射到形参的集合对象中作为数据
  4. @RequestMapping("/listParamForJson")
  5. @ResponseBody
  6. public String listParamForJson(@RequestBody List<String> likes){
  7. System.out.println("list common(json)参数传递 list ==> "+likes);
  8. return "{'module':'list common for json param'}";
  9. }
  10. //POJO参数:json格式
  11. //1.开启json数据格式的自动转换,在配置类中开启@EnableWebMvc
  12. //2.使用@RequestBody注解将外部传递的json数据映射到形参的实体类对象中,要求属性名称一一对应
  13. @RequestMapping("/pojoParamForJson")
  14. @ResponseBody
  15. public String pojoParamForJson(@RequestBody User user){
  16. System.out.println("pojo(json)参数传递 user ==> "+user);
  17. return "{'module':'pojo for json param'}";
  18. }
  19. //集合参数:json格式
  20. //1.开启json数据格式的自动转换,在配置类中开启@EnableWebMvc
  21. //2.使用@RequestBody注解将外部传递的json数组数据映射到形参的保存实体类对象的集合对象中,要求属性名称一一对应
  22. @RequestMapping("/listPojoParamForJson")
  23. @ResponseBody
  24. public String listPojoParamForJson(@RequestBody List<User> list){
  25. System.out.println("list pojo(json)参数传递 list ==> "+list);
  26. return "{'module':'list pojo for json param'}";
  27. }

3.2.2 Postman发送json格式参数

day04_SpringMVC - 图15

day04_SpringMVC - 图16

3.2.3 核心API总结

  1. # @RequestBody与@RequestParam区别
  2. 1. 区别
  3. @RequestParam用于接收url地址传参,表单传参【application/x-www-form-urlencoded
  4. @RequestBody用于接收json数据【application/json
  5. 2. 应用
  6. 后期开发中,发送json格式数据为主,@RequestBody应用较广
  7. 如果发送非json格式数据,选用@RequestParam接收请求参数
  1. # url格式请求参数
  2. 1. @RequestParam
  3. 接收集合类型的参数
  4. # json格式请求参数
  5. 1. 记得导入jackSon工具包(实现jsonpojo之间的数据转换)
  6. 2. @EnableWebMvc
  7. 开启webmvc功能(功能之一: 自动实现jsonpojo转换)
  8. 3. @RequestBody
  9. 在参数前面添加,用于接收json格式参数映射到pojo

3.3 特殊的情况

3.3.1 请求参数名称不一致

  1. # @RequestParam
  2. 1. value : 指定前端的属性名映射到某个参数上
  3. 使用前提: 形参名跟前端name属性名不一致
  4. 2. required:用于指定此参数是否必传
  5. true: (默认)表示必须要传,只要前端声明有name属性,不填属性值,也是有的
  6. 3. defaultValue:如果前端此参数值没有设置,这里参数会指定一个默认值。
  1. //普通参数:请求参数名与形参名不同时,使用@RequestParam注解关联请求参数名称与形参名称之间的关系
  2. @RequestMapping("/commonParamDifferentName")
  3. @ResponseBody
  4. public String commonParamDifferentName(@RequestParam("name") String userName , int age){
  5. System.out.println("普通参数传递 userName ==> "+userName);
  6. System.out.println("普通参数传递 age ==> "+age);
  7. return "{'module':'common param different name'}";
  8. }

day04_SpringMVC - 图17

3.3.2 编码过滤器

  1. 1. 如果请求携带了中文有乱码该怎么办呢? (tomcat8以上, post有中文乱码)
  2. 2. 我们在web阶段自己编写过编码过滤器,在SpringMVC中已经提供好了编码过滤器,我们直接使用即可
  3. 3. ServletContainersInitConfig配置类中进行配置即可
  1. public class ServletContainersInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
  2. protected Class<?>[] getRootConfigClasses() {
  3. return new Class[0];
  4. }
  5. protected Class<?>[] getServletConfigClasses() {
  6. return new Class[]{SpringMvcConfig.class};
  7. }
  8. protected String[] getServletMappings() {
  9. return new String[]{"/"};
  10. }
  11. //post请求乱码处理
  12. @Override
  13. protected Filter[] getServletFilters() {
  14. //spring封装的过滤器, 拦截所有的请求,如果是post请求,就将编码修改为指定编码
  15. CharacterEncodingFilter filter = new CharacterEncodingFilter();
  16. filter.setEncoding("UTF-8");
  17. return new Filter[]{filter};
  18. }
  19. }

3.3.3 日期处理

day04_SpringMVC - 图18

需要注意的是 使用@DateTimeFormat 需要 配置 @EnableWebMvc

  1. //日期参数
  2. //使用@DateTimeFormat注解设置日期类型数据格式,默认格式yyyy/MM/dd
  3. @RequestMapping("/dataParam")
  4. @ResponseBody
  5. public String dataParam(Date date,
  6. @DateTimeFormat(pattern="yyyy-MM-dd") Date date1,
  7. @DateTimeFormat(pattern="yyyy/MM/dd HH:mm:ss") Date date2){
  8. System.out.println("参数传递 date ==> "+date);
  9. System.out.println("参数传递 date1(yyyy-MM-dd) ==> "+date1);
  10. System.out.println("参数传递 date2(yyyy/MM/dd HH:mm:ss) ==> "+date2);
  11. return "{'module':'data param'}";
  12. }

4. 响应

  1. # SpringMVC对响应的封装可以分为以下两类
  2. 1. 响应页面
  3. 用于同步请求,了解即可
  4. 2. 响应数据
  5. 1). 文本数据
  6. 2). json数据(常用)

核心API

  1. # @ResponseBody
  2. 1. 类型:方法注解|方法返回参数之上
  3. 2. 位置:SpringMVC控制器方法定义上方
  4. 3. 作用:设置当前控制器返回值作为响应体
  5. 4. 只要配置好对应的环境 (需要导入jackson, 必须@EnableWebMvc)
  6. 那么springmvc会自动将javabean返回值转成json格式字符串

实例代码

  1. @Controller
  2. public class UserController {
  3. //响应页面/跳转页面
  4. //返回值为String类型,设置返回值为页面名称,即可实现页面跳转
  5. @RequestMapping("/toJumpPage")
  6. public String toJumpPage(){
  7. System.out.println("跳转页面");
  8. return "page.jsp";
  9. }
  10. //响应文本数据
  11. //返回值为String类型,设置返回值为任意字符串信息,即可实现返回指定字符串信息,需要依赖@ResponseBody注解
  12. @RequestMapping("/toText")
  13. @ResponseBody
  14. public String toText(){
  15. System.out.println("返回纯文本数据");
  16. return "response text";
  17. }
  18. //响应POJO对象
  19. //返回值为实体类对象,设置返回值为实体类类型,即可实现返回对应对象的json数据,需要依赖@ResponseBody注解和@EnableWebMvc注解
  20. @RequestMapping("/toJsonPOJO")
  21. @ResponseBody
  22. public User toJsonPOJO(){
  23. System.out.println("返回json对象数据");
  24. User user = new User();
  25. user.setName("itcast");
  26. user.setAge(15);
  27. return user;
  28. }
  29. //响应POJO集合对象
  30. //返回值为集合对象,设置返回值为集合类型,即可实现返回对应集合的json数组数据,需要依赖@ResponseBody注解和@EnableWebMvc注解
  31. @RequestMapping("/toJsonList")
  32. @ResponseBody
  33. public List<User> toJsonList(){
  34. System.out.println("返回json集合数据");
  35. User user1 = new User();
  36. user1.setName("传智播客");
  37. user1.setAge(15);
  38. User user2 = new User();
  39. user2.setName("黑马程序员");
  40. user2.setAge(12);
  41. List<User> userList = new ArrayList<User>();
  42. userList.add(user1);
  43. userList.add(user2);
  44. return userList;
  45. }
  46. }

5. Springmvc对Restful风格的支持

5.1 Restful

  • Rest( Representational State Transfer) 直接翻译的意思是”表现层的状态转化”。
    一种网络资源的访问风格,定义了网络资源的访问方式

  • Restful是按照Rest风格访问网络资源

  • Rest风格访问路径
    http://localhost/user/1

    • 强调的点有2点:

      • 路径即资源(路径中只能使用名词,不能使用动词)
      • 用请求方式表达对资源的操纵行为

        • 比如:http://localhost/user/1 请求方式:GET 表示查询id=1的用户信息
          1. # 含义可以多个:
          2. 既可以是查询,也可以是删除,也可以是修改,也可以是添加
          3. 别人根本就不知道开发者在干嘛
  • 优点
     隐藏资源的访问行为,通过地址无法得知做的是何种操作(安全)
     书写简化

5.2 Rest行为约定方式

Restful 使用URL定位资源,用HTTP请求方式(GET,POST,PUT,DELETE)描述操作

 GET(查询) http://localhost/user GET
 POST(保存) http://localhost/user POST
 PUT(更新) http://localhost/user PUT
 DELETE(删除) http://localhost/user DELETE

注意:上述行为是约定方式,约定不是硬性规范,可以打破,所以称Rest风格,而不是Rest规范

5.3 Restful开发入门

  1. public class User {
  2. private String name;
  3. private int age;
  4. @Override
  5. public String toString() {
  6. return "User{" +
  7. "name='" + name + '\'' +
  8. ", age=" + age +
  9. '}';
  10. }
  11. public String getName() {
  12. return name;
  13. }
  14. public void setName(String name) {
  15. this.name = name;
  16. }
  17. public int getAge() {
  18. return age;
  19. }
  20. public void setAge(int age) {
  21. this.age = age;
  22. }
  23. }
  1. @Controller
  2. public class RestController {
  3. @RequestMapping(value = "/rest",method = RequestMethod.GET)
  4. @ResponseBody
  5. public String demo01(){
  6. System.out.println("findAll");
  7. return "findAll";
  8. }
  9. @RequestMapping(value = "/rest/{id}",method = RequestMethod.GET)
  10. @ResponseBody
  11. public String demo11(@PathVariable Integer id){
  12. System.out.println("findById : " + id);
  13. return "findById";
  14. }
  15. @RequestMapping(value = "/rest/{page}/{pageSize}",method = RequestMethod.GET)
  16. @ResponseBody
  17. public String demo12(@PathVariable Integer page,@PathVariable Integer pageSize){
  18. System.out.println("findByPage : " + page + "," + pageSize);
  19. return "findByPage";
  20. }
  21. @RequestMapping(value = "/rest",method = RequestMethod.DELETE)
  22. @ResponseBody
  23. public String demo02(){
  24. System.out.println("deleteAll");
  25. return "deleteAll";
  26. }
  27. @RequestMapping(value = "/rest/{id}",method = RequestMethod.DELETE)
  28. @ResponseBody
  29. public String demo21(@PathVariable Integer id){
  30. System.out.println("deleteById : " + id);
  31. return "deleteById";
  32. }
  33. @RequestMapping(value = "/rest",method = RequestMethod.POST)
  34. @ResponseBody
  35. public String demo03(@RequestBody User user){
  36. System.out.println("add: " + user);
  37. return "add";
  38. }
  39. @RequestMapping(value = "/rest",method = RequestMethod.PUT)
  40. @ResponseBody
  41. public String demo04(){
  42. System.out.println("update");
  43. return "update";
  44. }
  45. }

5.4 Restful快速开发

  1. /*
  2. 复合注解 : A和B注解作为C的元注解, 那么C= A+B
  3. @RestController = @Controller + @ResponseBody
  4. */
  5. //@Controller
  6. //@ResponseBody // 表示每个方法响应数据都直接走响应体
  7. @RestController
  8. @RequestMapping("/rest")
  9. public class RestfulController {
  10. // @RequestMapping(value = "/rest",method = RequestMethod.GET)
  11. // @GetMapping(value = "/rest")
  12. @GetMapping
  13. public String demo01(){
  14. System.out.println("findAll");
  15. return "findAll";
  16. }
  17. // @RequestMapping(value = "/rest/{id}",method = RequestMethod.GET)
  18. @GetMapping("/{id}")
  19. public String demo11(@PathVariable Integer id){
  20. System.out.println("findById : " + id);
  21. return "findById";
  22. }
  23. // @RequestMapping(value = "/rest/{page}/{pageSize}",method = RequestMethod.GET)
  24. @GetMapping("/{page}/{pageSize}")
  25. public String demo12(@PathVariable Integer page,@PathVariable Integer pageSize){
  26. System.out.println("findByPage : " + page + "," + pageSize);
  27. return "findByPage";
  28. }
  29. // @RequestMapping(value = "/rest",method = RequestMethod.DELETE)
  30. @DeleteMapping
  31. public String demo02(){
  32. System.out.println("deleteAll");
  33. return "deleteAll";
  34. }
  35. // @RequestMapping(value = "/rest/{id}",method = RequestMethod.DELETE)
  36. @DeleteMapping("/{id}")
  37. public String demo21(@PathVariable Integer id){
  38. System.out.println("deleteById : " + id);
  39. return "deleteById";
  40. }
  41. // @RequestMapping(value = "/rest",method = RequestMethod.POST)
  42. @PostMapping
  43. public String demo03(@RequestBody User user){
  44. System.out.println("add: " + user);
  45. return "add";
  46. }
  47. // @RequestMapping(value = "/rest",method = RequestMethod.PUT)
  48. @PutMapping
  49. public String demo04(){
  50. System.out.println("update");
  51. return "update";
  52. }
  53. }

6. 案例:基于RESTful页面数据交互

导入素材中的代码 springmvc_07_rest_case

作业 : 改成前后端分离

总结:

1.三层架构与MVC架构的关系?

  1. 三层架构包含数据访问层、业务逻辑层、web层(servlet html model);
  2. MVC架构是对三层架构中的web层的再细粒度划分:解耦 提高代码复用 关注点分离;

2.sringmvc启动流程?

  1. 1.tomcat启动时,底层根据java提供的SPI机制,会自动加载spring-web-5.2.10.RELEASE.jar!\META-INF\services\javax.servlet.ServletContainerInitializer文件中的类:SpringServletContainerInitializer
  2. 并调用onStartup方法,该方法会收集当前项目中所有实现WebApplicationInitializer接口的类,并封装到set集合中农,然后注入onStartup方法中(SPI
  3. 2.SpringServletContainerInitializer下的onStartup方法执行时,会循环调用一切实现WebApplicationInitializer接口的对象中的onStartup方法
  4. 3.我们工程中ServletContainersInitConfig最后也实现了WebApplicationInitializer,所以它的onStartup也会被调用,该方法会间接调用初始化IOC容器的方法和核心调度器DispatchServlet,并设置拦截规则“/”;

3.springmvc访问流程?

  1. 1.前端(浏览器)发送请求到后台,被tomcat接收
  2. 2.tomcat调用DispatchServlet核心调度器处理当前的请求;
  3. 3.DispatchServlet会根据请求的url地址找具体的处理器方法,并调用
  4. 4.处理器方法执行完毕,返回的数据被DispatchServlet响应给前端

4.springmvc请求相关的注解有哪些?

  1. @ReqeustMapping 建立请求地址与处理器方法之间的关系,作用在类和方法之上;
  2. 属性:
  3. value或者path:指定请求路径
  4. method:指定请求方法 get delete put post
  5. 4中衍生注解:
  6. @GetMapping @DeleteMapping @PutMapping @PostMapping
  7. @Controller
  8. @RestController=@Controller + @Responbody
  9. 关于参数处理的注解:
  10. @ReqeustParam:解决请求参数与方法入参不一致的情况
  11. 属性:
  12. value:指定请求参数名称
  13. required: 默认是true,定义是否必须传入;
  14. defaultValue:设置默认值
  15. @RequestBoy:作用是接收前端ajax发送的json格式数据,并调用jackson工具自动实现jsonjava对象的功能
  16. 注解作用在方法的入参之上;
  17. @DateTimeFormat(pattern="日志表达式")
  18. 要想使用springmvc的这些扩展功能,前提是开启:@EnalbeWebMvc
  19. 如何接收resetfull路径中的参数?
  20. 使用@PathVariable("指定路径参数的名称")
  21. 响应数据:
  22. @ResponseBody:
  23. 特点:作用方法之上或者方法的返回值之上
  24. 作用:如果方法的返回值是基本类型+string,则直接返回
  25. 如果方法的返回值是一些负载的pojo