1.RESTful概述
1.1、 什么是REST
作者:
REST 仅仅是一种架构的风格,并不是真正的架构,也不是一个软件,不是一种新的的技术,而是一种思想。
而学习REST的关键,不是任何的API或者实现方式,而是这种思想。
1.2、 什么是RESTful
1.3、 如何统一接口规则
一般我们会借助于HTTP协议中的请求方法来表明对资源的操作:
举例,
以前非REST时,我们的URL
查询用户: http://localhost/user/query?id=1 - GET
添加用户: http://localhost/user/insert - POST
修改用户: http://localhost/user/update - POST
删除用户: http://localhost/user/delete?id=1 - GET
遵循REST规范的URI定义:
查询用户: http://localhost/user - GET
添加用户: http://localhost/user - POST
修改用户: http://localhost/user - PUT
删除用户: http://localhost/user - DELETE
form表单有method:get,post,put,delete,(patch,head,options)
URL和URI的区别:
- URL:固定的,www.baidu.com www.czxy.com
- URI:地址是固定的,但是对应的具体操作不确定
综上:Restful是针对URI的编程模式
1.4、 响应数据示例
Restful中, 响应的数据都为json格式
location.href
1.5、 响应状态码
200 查询OK
201 新增成功
204 服务器处理成功,但是没有返回值
400 参数传递失败,要么类型不匹配,要么缺少参数
501:接口还未实现
2、 REST实现用户CRUD
当使用Restful风格之后,我们开发前后端的时候,一定会先对后端进行测试,然后在提供服务给前端调用
2.1、 根据ID查询用户
根据REST的原则,我们查询后需要根据结果返回不同的状态码:
资源存在:200+数据
资源不存在:404 找不到
内部异常:500
这里通过ResponseEntity来封装响应的结果,包含两部分内容:数据和状态码
2.1.1 Service
@Service
@Transactional
public class UserService {
@Resource
private UserMapper userMapper;
public User queryById(Long id){
return this.userMapper.selectByPrimaryKey(id);
}
}
2.1.2 Controller
- @RestController:组合注解,相当于@Controller+@ResponseBody两个注解的结合
- @GetMapping:组合注解,相当于@RequestMapping(method = RequestMethod.GET)
- @PathVariable:获取地址栏中的数据
/**
* 采用Restful风格进行用户的CRUD操作
*/
@RestController
@RequestMapping("/rest")
public class RestUserController {
@Autowired
private UserService userService;
/**
* 根据id查找用户信息
* url:http://localhost:8080/rest/123
* 请求方式method:get
* 返回数据格式:json,状态码+数据
* @PathVariable:从地址栏获取参数
* @GetMapping:表明此方法只接受get请求,{id}是一个动态参数
*/
@GetMapping("/{id}")
public ResponseEntity<User> findUserById(@PathVariable("id") Integer id){
try {
User user = userService.findUserById(id);
if (user!=null) {
// 返回 200 + 数据
// 第一个参数:数据
// 第二个参数:状态码,枚举类型
return new ResponseEntity<>(user,HttpStatus.OK);
}else{
// 返回404
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
} catch (Exception e) {
e.printStackTrace();
// 返回500
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
}
}
2.1.3 测试
采用Postman,专业的测试rest接口的工具
2.2、 分页查找用户
分页组件:PageHelper
与SpringBoot整合,
<!-- https://mvnrepository.com/artifact/com.github.pagehelper/pagehelper-spring-boot-starter -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.5</version>
</dependency>
2.2.1 Service
public PageResult queryUserByPage(Integer page,Integer rows){
// 分页
PageHelper.startPage(page,rows);
// 查找数据
List<User> users = userMapper.select(null);
// 封装分页信息
PageInfo<User> info = new PageInfo<>(users);
// 组装PageResult
PageResult pageResult = new PageResult();
// 填充total
pageResult.setTotal(info.getTotal());
// 数据
pageResult.setRows(info.getList());
return pageResult;
}
2.2.2 Controller
@GetMapping
public ResponseEntity<PageResult> findUserByPage(Integer page,Integer rows){
try {
PageResult pageResult = userService.findUserByPage(page, rows);
return new ResponseEntity<>(pageResult,HttpStatus.OK);
} catch (Exception e) {
e.printStackTrace();
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
}
}
2.2.3 测试
-
请求
-
响应
2.3、 新增用户
在原来的新增用户功能中,我们返回的结果包含了status,也就是状态,这不符合REST风格。响应状态应该包含在header中
并且新增成功,应返回201状态码
2.3.1 service
public void addUser(User user){
this.userMapper.insert(user);
}
2.3.2 Controller
- @PostMapping:组合注解,相当于@RequestMapping(method = RequestMethod.POST)的缩写
@PostMapping
public ResponseEntity<Void> addUser(User user){
try {
userService.addUser(user);
return new ResponseEntity<Void>(HttpStatus.CREATED);
} catch (Exception e) {
e.printStackTrace();
// 出现异常,返回500
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
}
}
2.3.3 测试
-
请求
-
响应
2.4、 修改用户
修改成功,但是没有结果返回,根据REST原则,返回204:
2.4.1 Service
public void updateUser(User user){
this.userMapper.updateByPrimaryKey(user);
}
2.4.2 Controller
- PutMapping:@RequestMapping(method = RequestMethod.PUT)的缩写
@PutMapping
public ResponseEntity<Void> modifyUser(User user){
try {
userService.updateUser(user);
return new ResponseEntity<Void>(HttpStatus.NO_CONTENT);
} catch (Exception e) {
e.printStackTrace();
// 出现异常,返回500
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
}
}
2.4.3 测试:
-
请求
-
响应
2.5、 删除用户
删除成功,但是没有结果返回,根据REST原则,返回204。
2.5.1 Service
public void deleteById(Long id){
this.userMapper.deleteByPrimaryKey(id);
}
2.5.2 Controller
- @DeleteMapping:组合注解,相当于@RequestMapping(method = RequestMethod.Delete)的缩写
@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteUser(@PathVariable Long id){
try {
userService.deleteById(id);
return new ResponseEntity<Void>(HttpStatus.NO_CONTENT);
} catch (Exception e) {
e.printStackTrace();
// 出现异常,返回500
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
}
}
2.5.3 测试:
-
请求
-
响应
2.6 总结
1 URL和URI的区别
2 RestFul面向URI的编程方式
3 注解:
- RestController
- PathVariable
- GetMapping
- PostMapping
- PutMapping
- DeleteMapping
4、返回数据ResponseEntity:数据+状态码
5、状态码
- 200 查询ok
- 201 新增ok
- 204 修改或者删除OK
- 404 找不到
- 500 异常