SpringMVC
- SpringMVC简介
- 请求与响应
- REST风格
- SSM整合(注解版)
- 拦截器
# 学习目标
1. 掌握基于SpringMVC获取请求参数与响应json数据操作
2. 熟练应用基于REST风格的请求路径设置与参数传递
3. 能够根据实际业务建立前后端开发通信协议并进行实现
4. 基于SSM整合技术开发任意业务模块功能
1. SpringMVC简介
1.1 SpringMVC概述
1.1.1 请求响应模式演进过程
三层架构
- 表现层:负责数据展示,跟前端打交道(web,view,controller)
- 业务层:负责业务处理(service)
- 数据层:负责数据操作,跟数据库打交道(dao)
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+数据)响应给前端浏览器,控制器、视图资源和展示的数据是耦合到一块的,分层不明显;
弊端:页面、数据和控制器耦合到一块,代码的复用性很差,可维护性非常低;
同步请求场景下的springMVC开发
说明:mvc架构则将web层的控制器(servlet|controller)、视图资源、展示的数据model解耦分层管理,方便维护;
异步请求场景下的springMVC开发
说明:前后端直接通过json进行异步交互,格式统一,维护性较好;
说白了,就是将mvc架构中view视图层提取出来独立作为前端资源部署,然后后端控制层(controller)将model转化成json数据与前端进行交互;
1.1.2 SpringMVC概述
1. SpringMVC是一种基于Java实现MVC模型的轻量级Web框架
1). 底层基于Spring
2). 封装了web三大组件(Servlet,Filter,Listener)
2. 优点
1). 使用简单,开发便捷(相比于Servlet)
2). 灵活性强
1.2 入门案例
1.2.1 入门案例编写
①: 导入SpringMVC坐标与Servlet坐标
<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.10.RELEASE</version>
</dependency>
②:初始化SpringMVC环境(同Spring环境)
//springmvc配置类,本质上还是一个spring配置类
@Configuration
@ComponentScan("com.itheima.controller")
public class SpringMvcConfig {
}
③:创建SpringMVC控制器类(等同于Servlet功能)
//定义表现层控制器bean
@Controller
public class UserController {
//设置映射路径为/save,即外部访问路径
@RequestMapping("/save")
//设置当前操作返回结果为字符串
@ResponseBody
public String save(){
System.out.println("user save ...");
return "hello";
}
}
④:初始化Servlet容器,加载SpringMVC环境,并设置SpringMVC请求拦截的路径
//AbstractDispatcherServletInitializer类是SpringMVC提供的快速初始化Web3.0容器的抽象类
//web容器配置类
public class ServletContainersInitConfig extends AbstractDispatcherServletInitializer {
//加载springmvc配置类,产生springmvc容器(本质还是spring容器)
protected WebApplicationContext createServletApplicationContext() {
//初始化WebApplicationContext对象
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
//加载指定配置类
ctx.register(SpringMvcConfig.class);
return ctx;
}
//设置由springmvc控制器处理的请求映射路径
protected String[] getServletMappings() {
return new String[]{"/"};
}
//加载spring配置类
protected WebApplicationContext createRootApplicationContext() {
return null;
}
}
⑤:将项目部署到tomcat,并 使用浏览器测试请求
1.2.2 核心API
# @Controller
1. 类型:**类注解**
2. 位置:SpringMVC控制器类定义上方
3. 作用:设定SpringMVC的核心控制器bean
4. 范例:
@Controller
public class UserController {
}
# @RequestMapping
1. 类型:方法注解
2. 位置:SpringMVC控制器方法定义上方
3. 作用:设置当前控制器方法请求访问路径
说白了就是建立请求路径与处理器方法之间的映射关系
4. 范例:
@RequestMapping("/save")
public void save(){
System.out.println("user save ...");
}
# @ResponseBody
1. 类型:方法注解
2. 位置:SpringMVC控制器方法定义上方
3. 作用:设置当前控制器方法响应体内容为当前返回值,无需解析
说白了,就是将方法返回值序列化成字符串给前端返回;
4. 范例:
@RequestMapping("/save")
@ResponseBody
public String save(){
System.out.println("user save ...");
return "hello";
}
1.3 入门案例工作流程分析
SPI:service provider interface :服务提供接口
大白话:官方给开发者提供一个公共的接口标准(比如:jdbc提供Driver接口标准)
然后各个实现方法实现这个接口,然后将指向放在资源包下META-INF/services下,
文件名称就是这个公共的接口名称,而文件的内容就是该接口的实现;
这样,我们只需遵循这个标准,实现方会自动加载这个文件下的实现类,做具体的操作;
类似于快递柜,官方安装快递柜,邮递员只需遵循快递柜的使用规范,将快递正确放入,我们就是可以按照自己的方式取获取快速;
# 启动服务器初始化过程
0. tomcat -> ServletContainersInitConfig -> SpringMvcConfig -> UserController
1. tomcat的启动执时,根据SPI机制加载ServletContainersInitConfig类
1). spring-web.jar下有META-INF/services/javax.servlet.ServletContainerInitializer文件
2). 此文件中配置实现类 org.springframework.web.SpringServletContainerInitializer
3). 此类会被tomcat所加载(SPI机制),此类上的有个配置@HandlesTypes({WebApplicationInitializer.class})
4). 此接口WebApplicationInitializer的所有实现类都会被加载封装到set集合中,通过onStartup方法传入;
(看SpringServletContainerInitializer的onStartup)
5). 而我们入门案例中的ServletContainersInitConfig类就是WebApplicationInitializer实现类,所以也会被运行
2. ServletContainersInitConfig类的方法会被运行
1). createServletApplicationContext方法运行,加载springmvc配置类
2). getServletMappings方法运行, 给DispatcherServlet类设置访问路径为/ (表示拦截所有)
3. SpringMvcConfig类配置的注解生效
1). @ComponentScan("com.itheima.controller")
2). springmvc底层开始扫描 com.itheima.controller包
4. UserController类生效
1). @Controller
表示此bean会添加到springmvc的ioc容器
2). @RequestMapping("/save")
设置save方法的访问路径为 /save
3). @ResponseBody
方法的的返回值String将会通过响应体返回给前端
总之,springmvc通过spi机制调用 SpringServletContainerInitializer中的onstart方法来完成IOC容器以及核心调度器初始化的操作;
# 问题:
1. 入门案例是一个web项目,为何不写web.xml文件?
SPI机制: ServletContainerInitializer
2. 入门案例为何不写Servlet?
springMVC底层封装了DispatcherServlet,它拦截所有请求,然后分发给Controller.
# 单次请求过程
0. 浏览器(前端) -> (后端)tomcat -> DispatcherServlet -> UserController.save
1. 前端发送请求 http://localhost:8080/save
2. http://localhost:8080会找到tomcat(web容器-》servlet容器)
3. tomcat接收到请求,发现spingmvc中有个DispatcherServlet的拦截路径为/,所以就将请求交给DispatcherServlet,service方法会运行
4. DispatcherServlet会找到/save对应的控制器方法UserController.save方法,然后调用此方法
5. UserController.save方法运行之后,有String类型的返回值hello,通过响应体返回给前端
ServletContainersInitConfig的常用写法
public class ServletContainersInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
//加载springmvc配置的
protected Class<?>[] getServletConfigClasses() {
return new Class[]{SpringMvcConfig.class};
}
//设置由springmvc控制器处理的请求映射路径
protected String[] getServletMappings() {
return new String[]{"/"};
}
//加载spring配置类
protected Class<?>[] getRootConfigClasses() {
return new Class[0];
}
}
1.4 PostMan
1.4.1 Postman简介
Postman是一款功能强大的网页调试与发送网页HTTP请求的Chrome插件
测试工具作用:常用于进行接口测试
特征: 简单, 实用,美观, 大方
1.4.2 Postman基本使用
- 注册登录 (联网)
- 创建工作空间/进入工作空间
- 发起请求测试结果
2. RequestMapping注解
作用: RequestMapping 注解,用于建立请求路径与方法的对应关系。
2.1 编写位置
# 编写位置:
1. 类上:
窄化路径,访问此类中的方法时,必须加上类上的路径
2. 方法:
建立路径与方法的对应关系
示例代码
@Controller
//类上方配置的请求映射与方法上面配置的请求映射连接在一起,形成完整的请求映射路径
@RequestMapping("/user")
public class UserController {
//请求路径映射
@RequestMapping("/save")
@ResponseBody
public String save(){
System.out.println("user save ...");
return "hello";
}
//请求路径映射
@RequestMapping("/delete")
@ResponseBody
public String delete(){
System.out.println("user delete ...");
return "hello";
}
}
2.2 常用属性
# @RequestMapping注解常用属性
1. value或者path: 用来指定虚拟路径,value=可以省略
2. method: 用来限定请求的方式 (restful风格)
1). 不写,默认什么请求方式都可以
2). 写了,指定了请求方式,如果不匹配就会响应405状态码(错误)
示例代码:
@Controller
@RequestMapping("/role")
public class RoleController {
@RequestMapping(value = "/save",
method = RequestMethod.GET)
@ResponseBody
public String save(){
System.out.println("RoleController save...");
return "hello";
}
@RequestMapping(value = "/delete",
method = RequestMethod.POST)
@ResponseBody
public String delete(){
System.out.println("RoleController delete...");
return "hello";
}
}
3. 请求 (重点)
# SpringMVC的请求处理可以分为两大类:
这里说的同步请求和异步请求指的是前端
1. 同步请求
0). 特点: 同步请求的响应内容会刷新整个网页
1). url格式的请求参数
2). 响应: 请求转发
2. 异步请求 (主流!!!)
0). 特点: 响应内容只会让网页局部刷新
ajax/json (封装库,框架 axios/vue...)
1). 请求参数
url格式 name=value&name=value...
json格式
2). 响应
字符串
json格式
# SpringMvc对请求和响应进行了封装
1. 我们的控制器方法可以接收请求参数
2. 如果请求携带以下类型的数据,SpringMVC会自动帮我们接收,并且解析之后传递给方法进行使用
3. 使用方式: 直接定义方法形参
4. 注意: 方法上的形参名称必须要和请求参数名称保持一致
1).基本数据类型和string
2).pojo类型
3).数组类型
4).集合类型
3.1 获取url格式的请求参数
# url格式参数常见类型
1. 基本数据类型和string
2. pojo类型
3. 数组类型
4. 集合类型
3.1.1 核心代码
导入素材中 springmvc_03_request_param
@Controller
public class UserController {
//普通参数:请求参数与形参名称对应即可完成参数传递
@RequestMapping("/commonParam")
@ResponseBody
public String commonParam(String name ,int age){
System.out.println("普通参数传递 name ==> "+name);
System.out.println("普通参数传递 age ==> "+age);
return "hello";
}
//POJO参数:请求参数与形参对象中的属性对应即可完成参数传递
@RequestMapping("/pojoParam")
@ResponseBody
public String pojoParam(User user){
System.out.println("pojo参数传递 user ==> "+user);
return "hello";
}
//嵌套POJO参数:嵌套属性按照层次结构设定名称即可完成参数传递
@RequestMapping("/pojoContainPojoParam")
@ResponseBody
public String pojoContainPojoParam(User user){
System.out.println("pojo嵌套pojo参数传递 user ==> "+user);
return "hello";
}
//数组参数:同名请求参数可以直接映射到对应名称的形参数组对象中
@RequestMapping("/arrayParam")
@ResponseBody
public String arrayParam(String[] likes){
System.out.println("数组参数传递 likes ==> "+ Arrays.toString(likes));
return "hello";
}
//集合参数:同名请求参数可以使用@RequestParam注解映射到对应名称的集合对象中作为数据
@RequestMapping("/listParam")
@ResponseBody
public String listParam(@RequestParam List<String> likes){
System.out.println("集合参数传递 likes ==> "+ likes);
return "hello";
}
}
3.1.2 Postman发送url格式参数
3.2 获取json格式的请求参数
# json格式数据
1. 对象 { }
2. 数组 [ ]
# json格式请求参数常见类型
1. json数组
String [] / int[]
["a","b","c"]
2. json对象(POJO)
User
{"name":"zs","age" : 18}
3. json数组(POJO)
List<User>
[{"name":"zs","age" : 18},{"name":"ls","age":19}]
# java中的json转换工具
1. fastJson ( alibaba的 )
1). json格式字符串变成 pojo对象
2). pojo对象变成json格式字符串
2. JackSon (springMVC底层使用)
3. gson
# web阶段封装的一个工具类 BaseController
1. 接收json格式的请求参数 变成 pojo
2. 将pojo的响应数据 变成 json格式字符串
3.2.1 使用步骤
①:添加json数据转换相关坐标
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.0</version>
</dependency>
②:设置发送json数据(请求body中添加json数据)
③:开启自动转换json数据的支持
@Configuration
@ComponentScan("com.itheima.controller")
//开启json数据类型自动转换
//@EnableWebMvc注解功能强大,该注解整合了多个功能,此处仅使用其中一部分功能,即json数据进行自动类型转换
@EnableWebMvc
public class SpringMvcConfig {
}
④:设置接收json数据
@RequestMapping("/listPojoParamForJson")
@ResponseBody
public String listPojoParamForJson(@RequestBody List<User> list){
System.out.println("list pojo(json)参数传递 list ==> "+list);
return "{'module':'list pojo for json param'}";
}
核心代码
//集合参数:json格式
//1.开启json数据格式的自动转换,在配置类中开启@EnableWebMvc
//2.使用@RequestBody注解将外部传递的json数组数据映射到形参的集合对象中作为数据
@RequestMapping("/listParamForJson")
@ResponseBody
public String listParamForJson(@RequestBody List<String> likes){
System.out.println("list common(json)参数传递 list ==> "+likes);
return "{'module':'list common for json param'}";
}
//POJO参数:json格式
//1.开启json数据格式的自动转换,在配置类中开启@EnableWebMvc
//2.使用@RequestBody注解将外部传递的json数据映射到形参的实体类对象中,要求属性名称一一对应
@RequestMapping("/pojoParamForJson")
@ResponseBody
public String pojoParamForJson(@RequestBody User user){
System.out.println("pojo(json)参数传递 user ==> "+user);
return "{'module':'pojo for json param'}";
}
//集合参数:json格式
//1.开启json数据格式的自动转换,在配置类中开启@EnableWebMvc
//2.使用@RequestBody注解将外部传递的json数组数据映射到形参的保存实体类对象的集合对象中,要求属性名称一一对应
@RequestMapping("/listPojoParamForJson")
@ResponseBody
public String listPojoParamForJson(@RequestBody List<User> list){
System.out.println("list pojo(json)参数传递 list ==> "+list);
return "{'module':'list pojo for json param'}";
}
3.2.2 Postman发送json格式参数
3.2.3 核心API总结
# @RequestBody与@RequestParam区别
1. 区别
@RequestParam用于接收url地址传参,表单传参【application/x-www-form-urlencoded】
@RequestBody用于接收json数据【application/json】
2. 应用
后期开发中,发送json格式数据为主,@RequestBody应用较广
如果发送非json格式数据,选用@RequestParam接收请求参数
# url格式请求参数
1. @RequestParam
接收集合类型的参数
# json格式请求参数
1. 记得导入jackSon工具包(实现json和pojo之间的数据转换)
2. @EnableWebMvc
开启webmvc功能(功能之一: 自动实现json和pojo转换)
3. @RequestBody
在参数前面添加,用于接收json格式参数映射到pojo上
3.3 特殊的情况
3.3.1 请求参数名称不一致
# @RequestParam
1. value : 指定前端的属性名映射到某个参数上
使用前提: 形参名跟前端name属性名不一致
2. required:用于指定此参数是否必传
true: (默认)表示必须要传,只要前端声明有name属性,不填属性值,也是有的
3. defaultValue:如果前端此参数值没有设置,这里参数会指定一个默认值。
//普通参数:请求参数名与形参名不同时,使用@RequestParam注解关联请求参数名称与形参名称之间的关系
@RequestMapping("/commonParamDifferentName")
@ResponseBody
public String commonParamDifferentName(@RequestParam("name") String userName , int age){
System.out.println("普通参数传递 userName ==> "+userName);
System.out.println("普通参数传递 age ==> "+age);
return "{'module':'common param different name'}";
}
3.3.2 编码过滤器
1. 如果请求携带了中文有乱码该怎么办呢? (tomcat8以上, post有中文乱码)
2. 我们在web阶段自己编写过编码过滤器,在SpringMVC中已经提供好了编码过滤器,我们直接使用即可
3. 在ServletContainersInitConfig配置类中进行配置即可
public class ServletContainersInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
protected Class<?>[] getRootConfigClasses() {
return new Class[0];
}
protected Class<?>[] getServletConfigClasses() {
return new Class[]{SpringMvcConfig.class};
}
protected String[] getServletMappings() {
return new String[]{"/"};
}
//post请求乱码处理
@Override
protected Filter[] getServletFilters() {
//spring封装的过滤器, 拦截所有的请求,如果是post请求,就将编码修改为指定编码
CharacterEncodingFilter filter = new CharacterEncodingFilter();
filter.setEncoding("UTF-8");
return new Filter[]{filter};
}
}
3.3.3 日期处理
需要注意的是 使用@DateTimeFormat 需要 配置 @EnableWebMvc
//日期参数
//使用@DateTimeFormat注解设置日期类型数据格式,默认格式yyyy/MM/dd
@RequestMapping("/dataParam")
@ResponseBody
public String dataParam(Date date,
@DateTimeFormat(pattern="yyyy-MM-dd") Date date1,
@DateTimeFormat(pattern="yyyy/MM/dd HH:mm:ss") Date date2){
System.out.println("参数传递 date ==> "+date);
System.out.println("参数传递 date1(yyyy-MM-dd) ==> "+date1);
System.out.println("参数传递 date2(yyyy/MM/dd HH:mm:ss) ==> "+date2);
return "{'module':'data param'}";
}
4. 响应
# SpringMVC对响应的封装可以分为以下两类
1. 响应页面
用于同步请求,了解即可
2. 响应数据
1). 文本数据
2). json数据(常用)
核心API
# @ResponseBody
1. 类型:方法注解|方法返回参数之上
2. 位置:SpringMVC控制器方法定义上方
3. 作用:设置当前控制器返回值作为响应体
4. 只要配置好对应的环境 (需要导入jackson, 必须@EnableWebMvc)
那么springmvc会自动将javabean返回值转成json格式字符串
实例代码
@Controller
public class UserController {
//响应页面/跳转页面
//返回值为String类型,设置返回值为页面名称,即可实现页面跳转
@RequestMapping("/toJumpPage")
public String toJumpPage(){
System.out.println("跳转页面");
return "page.jsp";
}
//响应文本数据
//返回值为String类型,设置返回值为任意字符串信息,即可实现返回指定字符串信息,需要依赖@ResponseBody注解
@RequestMapping("/toText")
@ResponseBody
public String toText(){
System.out.println("返回纯文本数据");
return "response text";
}
//响应POJO对象
//返回值为实体类对象,设置返回值为实体类类型,即可实现返回对应对象的json数据,需要依赖@ResponseBody注解和@EnableWebMvc注解
@RequestMapping("/toJsonPOJO")
@ResponseBody
public User toJsonPOJO(){
System.out.println("返回json对象数据");
User user = new User();
user.setName("itcast");
user.setAge(15);
return user;
}
//响应POJO集合对象
//返回值为集合对象,设置返回值为集合类型,即可实现返回对应集合的json数组数据,需要依赖@ResponseBody注解和@EnableWebMvc注解
@RequestMapping("/toJsonList")
@ResponseBody
public List<User> toJsonList(){
System.out.println("返回json集合数据");
User user1 = new User();
user1.setName("传智播客");
user1.setAge(15);
User user2 = new User();
user2.setName("黑马程序员");
user2.setAge(12);
List<User> userList = new ArrayList<User>();
userList.add(user1);
userList.add(user2);
return userList;
}
}
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的用户信息
# 含义可以多个:
既可以是查询,也可以是删除,也可以是修改,也可以是添加
别人根本就不知道开发者在干嘛
- 比如:http://localhost/user/1 请求方式:GET 表示查询id=1的用户信息
优点
隐藏资源的访问行为,通过地址无法得知做的是何种操作(安全)
书写简化
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开发入门
public class User {
private String name;
private int age;
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
@Controller
public class RestController {
@RequestMapping(value = "/rest",method = RequestMethod.GET)
@ResponseBody
public String demo01(){
System.out.println("findAll");
return "findAll";
}
@RequestMapping(value = "/rest/{id}",method = RequestMethod.GET)
@ResponseBody
public String demo11(@PathVariable Integer id){
System.out.println("findById : " + id);
return "findById";
}
@RequestMapping(value = "/rest/{page}/{pageSize}",method = RequestMethod.GET)
@ResponseBody
public String demo12(@PathVariable Integer page,@PathVariable Integer pageSize){
System.out.println("findByPage : " + page + "," + pageSize);
return "findByPage";
}
@RequestMapping(value = "/rest",method = RequestMethod.DELETE)
@ResponseBody
public String demo02(){
System.out.println("deleteAll");
return "deleteAll";
}
@RequestMapping(value = "/rest/{id}",method = RequestMethod.DELETE)
@ResponseBody
public String demo21(@PathVariable Integer id){
System.out.println("deleteById : " + id);
return "deleteById";
}
@RequestMapping(value = "/rest",method = RequestMethod.POST)
@ResponseBody
public String demo03(@RequestBody User user){
System.out.println("add: " + user);
return "add";
}
@RequestMapping(value = "/rest",method = RequestMethod.PUT)
@ResponseBody
public String demo04(){
System.out.println("update");
return "update";
}
}
5.4 Restful快速开发
/*
复合注解 : A和B注解作为C的元注解, 那么C= A+B
@RestController = @Controller + @ResponseBody
*/
//@Controller
//@ResponseBody // 表示每个方法响应数据都直接走响应体
@RestController
@RequestMapping("/rest")
public class RestfulController {
// @RequestMapping(value = "/rest",method = RequestMethod.GET)
// @GetMapping(value = "/rest")
@GetMapping
public String demo01(){
System.out.println("findAll");
return "findAll";
}
// @RequestMapping(value = "/rest/{id}",method = RequestMethod.GET)
@GetMapping("/{id}")
public String demo11(@PathVariable Integer id){
System.out.println("findById : " + id);
return "findById";
}
// @RequestMapping(value = "/rest/{page}/{pageSize}",method = RequestMethod.GET)
@GetMapping("/{page}/{pageSize}")
public String demo12(@PathVariable Integer page,@PathVariable Integer pageSize){
System.out.println("findByPage : " + page + "," + pageSize);
return "findByPage";
}
// @RequestMapping(value = "/rest",method = RequestMethod.DELETE)
@DeleteMapping
public String demo02(){
System.out.println("deleteAll");
return "deleteAll";
}
// @RequestMapping(value = "/rest/{id}",method = RequestMethod.DELETE)
@DeleteMapping("/{id}")
public String demo21(@PathVariable Integer id){
System.out.println("deleteById : " + id);
return "deleteById";
}
// @RequestMapping(value = "/rest",method = RequestMethod.POST)
@PostMapping
public String demo03(@RequestBody User user){
System.out.println("add: " + user);
return "add";
}
// @RequestMapping(value = "/rest",method = RequestMethod.PUT)
@PutMapping
public String demo04(){
System.out.println("update");
return "update";
}
}
6. 案例:基于RESTful页面数据交互
导入素材中的代码 springmvc_07_rest_case
作业 : 改成前后端分离
总结:
1.三层架构与MVC架构的关系?
三层架构包含数据访问层、业务逻辑层、web层(servlet html model);
MVC架构是对三层架构中的web层的再细粒度划分:解耦 提高代码复用 关注点分离;
2.sringmvc启动流程?
1.tomcat启动时,底层根据java提供的SPI机制,会自动加载spring-web-5.2.10.RELEASE.jar!\META-INF\services\javax.servlet.ServletContainerInitializer文件中的类:SpringServletContainerInitializer
并调用onStartup方法,该方法会收集当前项目中所有实现WebApplicationInitializer接口的类,并封装到set集合中农,然后注入onStartup方法中(SPI)
2.SpringServletContainerInitializer下的onStartup方法执行时,会循环调用一切实现WebApplicationInitializer接口的对象中的onStartup方法
3.我们工程中ServletContainersInitConfig最后也实现了WebApplicationInitializer,所以它的onStartup也会被调用,该方法会间接调用初始化IOC容器的方法和核心调度器DispatchServlet,并设置拦截规则“/”;
3.springmvc访问流程?
1.前端(浏览器)发送请求到后台,被tomcat接收
2.tomcat调用DispatchServlet核心调度器处理当前的请求;
3.DispatchServlet会根据请求的url地址找具体的处理器方法,并调用
4.处理器方法执行完毕,返回的数据被DispatchServlet响应给前端
4.springmvc请求相关的注解有哪些?
@ReqeustMapping 建立请求地址与处理器方法之间的关系,作用在类和方法之上;
属性:
value或者path:指定请求路径
method:指定请求方法 get delete put post等
有4中衍生注解:
@GetMapping @DeleteMapping @PutMapping @PostMapping
@Controller
@RestController=@Controller + @Responbody
关于参数处理的注解:
@ReqeustParam:解决请求参数与方法入参不一致的情况
属性:
value:指定请求参数名称
required: 默认是true,定义是否必须传入;
defaultValue:设置默认值
@RequestBoy:作用是接收前端ajax发送的json格式数据,并调用jackson工具自动实现json转java对象的功能
注解作用在方法的入参之上;
@DateTimeFormat(pattern="日志表达式")
要想使用springmvc的这些扩展功能,前提是开启:@EnalbeWebMvc
如何接收resetfull路径中的参数?
使用@PathVariable("指定路径参数的名称")
响应数据:
@ResponseBody:
特点:作用方法之上或者方法的返回值之上
作用:如果方法的返回值是基本类型+string,则直接返回
如果方法的返回值是一些负载的pojo