一. SpringMVC概述
-
浏览器发送一个请求给后端服务器,后端服务器现在是使用Servlet来接收请求和数据
-
如果所有的处理都交给Servlet来处理的话,所有的东西都耦合在一起,对后期的维护和扩展极为不利
-
将后端服务器Servlet拆分成三层,分别是
web
、service
和dao
-
web层主要由servlet来处理,负责页面请求和数据的收集以及响应结果给前端
-
service层主要负责业务逻辑的处理
-
dao层主要负责数据的增删改查操作
-
-
servlet处理请求和数据的时候,存在的问题是一个servlet只能处理一个请求
-
针对web层进行了优化,采用了MVC设计模式,将其设计为
controller
、view
和Model
-
controller负责请求和数据的接收,接收后将其转发给service进行业务处理
-
service根据需要会调用dao对数据进行增删改查
-
dao把数据处理完后将结果交给service,service再交给controller
-
controller根据需求组装成Model和View,Model和View组合起来生成页面转发给前端浏览器
-
这样做的好处就是controller可以处理多个请求,并对请求进行分发,执行不同的业务操作。
-
随着互联网的发展,上面的模式因为是同步调用,性能慢慢的跟不是需求,所以异步调用慢慢的走到了前台,是现在比较流行的一种处理方式。
-
因为是异步调用,所以后端不需要返回view视图,将其去除
-
前端如果通过异步调用的方式进行交互,后台就需要将返回的数据转换成json格式进行返回
-
SpringMVC主要负责的就是
-
controller如何接收请求和数据
-
如何将请求和数据转发给业务层
-
如何将响应数据转换成json发回到前端
-
介绍了这么多,对SpringMVC进行一个定义
-
SpringMVC是一种基于Java实现MVC模型的轻量级Web框架
-
优点
-
使用简单、开发便捷(相比于Servlet)
-
灵活性强
-
二. 注解的含义
知识点1:@Controller
名称 | @Controller |
---|---|
类型 | 类注解 |
位置 | SpringMVC控制器类定义上方 |
作用 | 设定SpringMVC的核心控制器bean |
知识点2:@RequestMapping
名称 | @RequestMapping |
---|---|
类型 | 类注解或方法注解 |
位置 | SpringMVC控制器类或方法定义上方 |
作用 | 设置当前控制器方法请求访问路径 |
相关属性 | value(默认),请求访问路径 |
知识点3:@ResponseBody
名称 | @ResponseBody |
---|---|
类型 | 类注解或方法注解 |
位置 | SpringMVC控制器类或方法定义上方 |
作用 | 设置当前控制器方法响应内容为当前返回值,无需解析 |
说明:
-
该注解可以写在类上或者方法上
-
写在类上就是该类下的所有方法都有@ReponseBody功能
-
当方法上有@ReponseBody注解后
-
方法的返回值为字符串,会将其作为文本内容直接响应给前端
-
方法的返回值为对象,会将对象转换成JSON响应给前端
-
此处又使用到了类型转换,内部还是通过Converter接口的实现类完成的,所以Converter除了前面所说的功能外,它还可以实现:
-
对象转Json数据(POJO -> json)
-
集合转Json数据(Collection -> json)
知识点4:@ComponentScan
名称 | @ComponentScan |
---|---|
类型 | 类注解 |
位置 | 类定义上方 |
作用 | 设置spring配置类扫描路径,用于加载使用注解格式定义的bean |
相关属性 | excludeFilters:排除扫描路径中加载的bean,需要指定类别(type)和具体项(classes) includeFilters:加载指定的bean,需要指定类别(type)和具体项(classes) |
知识点5:@RequestParam
名称 | @RequestParam |
---|---|
类型 | 形参注解 |
位置 | SpringMVC控制器方法形参定义前面 |
作用 | 绑定请求参数与处理器方法形参间的关系 |
相关参数 | required:是否为必传参数 defaultValue:参数默认值 |
知识点6:@EnableWebMvc
名称 | @EnableWebMvc |
---|---|
类型 | 配置类注解 |
位置 | SpringMVC配置类定义上方 |
作用 | 开启SpringMVC多项辅助功能 |
知识点7:@RequestBody
名称 | @RequestBody |
---|---|
类型 | 形参注解 |
位置 | SpringMVC控制器方法形参定义前面 |
作用 | 将请求中请求体所包含的数据传递给请求参数,此注解一个处理器方法只能使用一次 |
@RequestBody与@RequestParam区别
-
区别
-
@RequestParam用于接收url地址传参,表单传参【application/x-www-form-urlencoded】
-
@RequestBody用于接收json数据【application/json】
-
-
应用
-
后期开发中,发送json格式数据为主,@RequestBody应用较广
-
如果发送非json格式数据,选用@RequestParam接收请求参数
-
知识点8:@DateTimeFormat
名称 | @DateTimeFormat |
---|---|
类型 | 形参注解 |
位置 | SpringMVC控制器方法形参前面 |
作用 | 设定日期时间型数据格式 |
相关属性 | pattern:指定日期时间格式字符串 |
知识点9:@PathVariable
名称 | @PathVariable |
---|---|
类型 | 形参注解 |
位置 | SpringMVC控制器方法形参定义前面 |
作用 | 绑定路径参数与处理器方法形参间的关系,要求路径参数名与形参名一一对应 |
关于接收参数,三个注解@RequestBody
、@RequestParam
、@PathVariable
,这三个注解之间的区别和应用分别是什么?
-
区别
-
@RequestParam用于接收url地址传参或表单传参
-
@RequestBody用于接收json数据
-
@PathVariable用于接收路径参数,使用{参数名称}描述路径参数
-
-
应用
-
后期开发中,发送请求参数超过1个时,以json格式为主,@RequestBody应用较广
-
如果发送非json格式数据,选用@RequestParam接收请求参数
-
采用RESTful进行开发,当参数数量较少时,例如1个,可以采用@PathVariable接收请求路径变量,通常用于传递id值
-
三. REST简介
-
REST(Representational State Transfer),表现形式状态转换,它是一种软件架构风格
当我们想表示一个网络资源的时候,可以使用两种方式:
-
传统风格资源描述形式
-
http://localhost/user/getById?id=1
查询id为1的用户信息 -
http://localhost/user/saveUser
保存用户信息
-
-
REST风格描述形式
-
http://localhost/user/1
-
http://localhost/user
-
-
传统方式一般是一个请求url对应一种操作,这样做不仅麻烦,也不安全,因为会程序的人读取了你的请求url地址,就大概知道该url实现的是一个什么样的操作。
查看REST风格的描述,你会发现请求地址变的简单了,并且光看请求URL并不是很能猜出来该URL的具体功能
所以REST的优点有:
-
隐藏资源的访问行为,无法通过地址得知对资源是何种操作
-
书写简化
但是我们的问题也随之而来了,一个相同的url地址即可以是新增也可以是修改或者查询,那么到底我们该如何区分该请求到底是什么操作呢?
-
按照REST风格访问资源时使用行为动作区分对资源进行了何种操作
-
http://localhost/users
查询全部用户信息 GET(查询) -
http://localhost/users/1
查询指定用户信息 GET(查询) -
http://localhost/users
添加用户信息 POST(新增/保存) -
http://localhost/users
修改用户信息 PUT(修改/更新) -
http://localhost/users/1
删除用户信息 DELETE(删除)
-
请求的方式比较多,但是比较常用的就4种,分别是GET
,POST
,PUT
,DELETE
。
按照不同的请求方式代表不同的操作类型。
-
发送GET请求是用来做查询
-
发送POST请求是用来做新增
-
发送PUT请求是用来做修改
-
发送DELETE请求是用来做删除
但是注意:
-
上述行为是约定方式,约定不是规范,可以打破,所以称REST风格,而不是REST规范
-
REST提供了对应的架构方式,按照这种架构设计项目可以降低开发的复杂性,提高系统的可伸缩性
-
REST中规定GET/POST/PUT/DELETE针对的是查询/新增/修改/删除,但是我们如果非要用GET请求做删除,这点在程序上运行是可以实现的
-
但是如果绝大多数人都遵循这种风格,你写的代码让别人读起来就有点莫名其妙了。
-
-
描述模块的名称通常使用复数,也就是加s的格式描述,表示此类资源,而非单个资源,例如:users、books、accounts......
清楚了什么是REST风格后,我们后期会经常提到一个概念叫RESTful
,那什么又是RESTful呢?
-
根据REST风格对资源进行访问称为RESTful。
后期我们在进行开发的过程中,大多是都是遵从REST风格来访问我们的后台服务,所以可以说咱们以后都是基于RESTful来进行开发的。
Restful小结
RESTful入门案例,我们需要学习的内容如下:
(1)设定Http请求动作(动词)
@RequestMapping(value="",method = RequestMethod.POST|GET|PUT|DELETE)
(2)设定请求参数(路径变量)
@RequestMapping(value="/users/{id}",method = RequestMethod.DELETE)
@ReponseBody
public String delete(@PathVariable Integer id){
}
四. 优化简化
做完了RESTful的开发,你会发现好麻烦,麻烦在哪?
问题1:每个方法的@RequestMapping注解中都定义了访问路径/books,重复性太高。
将@RequestMapping提到类上面,用来定义所有方法共同的访问路径。
问题2:每个方法的@RequestMapping注解中都要使用method属性定义请求方式,重复性太高。
使用@GetMapping @PostMapping @PutMapping @DeleteMapping代替
问题3:每个方法响应json都需要加上@ResponseBody注解,重复性太高。
1.将ResponseBody提到类上面,让所有的方法都有@ResponseBody的功能 2.使用@RestController注解替换@Controller与@ResponseBody注解,简化书写
知识点1:@RestController
名称 | @RestController |
---|---|
类型 | 类注解 |
位置 | 基于SpringMVC的RESTful开发控制器类定义上方 |
作用 | 设置当前控制器类为RESTful风格, 等同于@Controller与@ResponseBody两个注解组合功能 |
知识点2:@GetMapping @PostMapping @PutMapping @DeleteMapping
名称 | @GetMapping @PostMapping @PutMapping @DeleteMapping |
---|---|
类型 | 方法注解 |
位置 | 基于SpringMVC的RESTful开发控制器方法定义上方 |
作用 | 设置当前控制器方法请求访问路径与请求动作,每种对应一个请求动作, 例如@GetMapping对应GET请求 |
相关属性 | value(默认):请求访问路径 |
示例代码:
@RestController //@Controller + ReponseBody
@RequestMapping("/books")
public class BookController {
//@RequestMapping(method = RequestMethod.POST)
@PostMapping
public String save(@RequestBody Book book){
System.out.println("book save..." + book);
return "{'module':'book save'}";
}//@RequestMapping(value = "/{id}",method = RequestMethod.DELETE)
@DeleteMapping("/{id}")
public String delete(@PathVariable Integer id){
System.out.println("book delete..." + id);
return "{'module':'book delete'}";
}//@RequestMapping(method = RequestMethod.PUT)
@PutMapping
public String update(@RequestBody Book book){
System.out.println("book update..." + book);
return "{'module':'book update'}";
}//@RequestMapping(value = "/{id}",method = RequestMethod.GET)
@GetMapping("/{id}")
public String getById(@PathVariable Integer id){
System.out.println("book getById..." + id);
return "{'module':'book getById'}";
}//@RequestMapping(method = RequestMethod.GET)
@GetMapping
public String getAll(){
System.out.println("book getAll...");
return "{'module':'book getAll'}";
}
}