任务描述
任务要求
使用IDEA开发工具构建一个项目多模块工程。study-springboot-chapter17学习关于Springboot开发前端控制层,方便实现前后端分离
- 基于study-springboot工程,复制study-springboot-chapter17标准项目,坐标groupId(com.cbitedu)、artifactId(study-springboot-chapter17),其他默认
- 继承study-springboot工程依赖
- 构建Restful API
任务收获
- Spring Boot开发Restful API服务
- 学会使用JUnit完成单元测试
- 掌握web开发原理
- 熟悉SpringMVC的基础配置
任务准备
环境要求
- JDK1.8+
- MySQL8.0.27+
- Maven 3.6.1+
- IDEA/VSCode
数据库准备
sql
-- ----------------------------
-- Table structure for tb_user
-- ----------------------------
DROP TABLE IF EXISTS `tb_user`;
CREATE TABLE `tb_user` (
`id` bigint NOT NULL AUTO_INCREMENT,
`username` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '用户名',
`password` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '密码,加密存储',
`phone` varchar(11) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '注册手机号',
`created` datetime NOT NULL COMMENT '创建时间',
`salt` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '密码加密的salt值',
PRIMARY KEY (`id`) USING BTREE,
UNIQUE INDEX `username`(`username` ASC) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 5 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '用户表' ROW_FORMAT = DYNAMIC;
-- ----------------------------
-- Records of tb_user
-- ----------------------------
INSERT INTO `tb_user` VALUES (1, 'tosea', '44f871f0a390c5ca0731ebb0f5a17e73', '13037889034', '2019-04-11 11:36:45', '802ae2cb978b4cc2b5705e9e525f3c7d');
INSERT INTO `tb_user` VALUES (2, 'tellsea', 'a11a53405c18b7bd9793396a5ada044c', '18386474459', '2019-04-17 23:02:43', 'aabaf92f1d10459d84d2b0f076fb3fdd');
工程目录要求
study-springboot-chapter17
任务实施
前端控制层常用的@Controller、@RestController、@RequestMapping注解。
- @Controller:修饰class,用来创建处理http请求的对象
- @RestController:Spring4之后加入的注解,原来在@Controller中返回json需要@ResponseBody来配合,如果直接用@RestController替代@Controller就不需要再配置@ResponseBody,默认返回json格式
- @RequestMapping:配置url映射。现在更多的也会直接用以Http Method直接关联的映射注解来定义,比如:GetMapping、PostMapping、DeleteMapping、PutMapping等
下面我们通过使用Spring MVC来实现一组对User对象操作的RESTful API,配合注释详细说明在Spring MVC中如何映射HTTP请求、如何传参、如何编写单元测试。
RESTful API具体设计如下:
Method | 介绍 | 幂等 |
---|---|---|
GET | 数据的查询操作 | Yes |
HEAD | 与GET 相同, 区别是响应中不包含响应体. 可以用来获取资源的元数据, 如 header 等 |
Yes |
POST | 信息的创建:创建成功应该返回响应码 201 | No |
PATCH | 用于局部更新 从 POST 请求分出来的, POST 全量更新, PATCH 局部更新. | No |
PUT | 信息的更新 | Yes |
DELETE | 数据删除 | Yes |
OPTIONS | API 相关信息 如探测服务支持的所有Method , 或者检测服务通不通. |
Yes |
CONNECTED | 与服务器建立链接, 通过服务器代理客户端请求 说白了就是一个 HTTP 代理 | Yes |
TRACE | 对请求路径的环回测试 | Yes |
幂等, 上面表格中幂等的意思就是, 接口调2次和调1次结果一样, 既可以重复调用.
GET(SELECT):从服务器取出资源(一项或多项)。
POST(CREATE):在服务器新建一个资源。
PUT(UPDATE):在服务器更新资源(客户端提供改变后的完整资源)。
PATCH(UPDATE):在服务器更新资源(客户端提供改变的属性)。
DELETE(DELETE):从服务器删除资源。
例如:
响应码 | 介绍 |
---|---|
1xx | 请求已收到, 需要继续操作 |
2xx | 请求成功处理 |
3xx | 重定向, 需要进一步请求 |
4xx | 客户端错误 |
5xx | 服务器错误 |
定义User实体
kotlin
package com.cbitedu.springboot.entity;
import lombok.Data;
@Data
public class User {
private Long id;
private String username;
private String password;
private Integer age;
}
定义状态响应辅助类
kotlin
package com.cbitedu.springboot.utils;
import lombok.Builder;
import lombok.Data;
@Data
@Builder // 作用:调用时使用链式写法
public class ResultResponse {
private String code;
private String message;
private Object data;
}
@Data注解可以实现在编译器自动添加set和get函数的效果。该注解是lombok提供的,只需要在pom中引入加入下面的依赖就可以支持:
xml
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
实现对User对象的操作接口
typescript
package com.cbitedu.springboot.controller;
import com.cbitedu.springboot.entity.User;
import com.cbitedu.springboot.utils.ResultResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
@RestController
@Slf4j
@RequestMapping(value = "demo") // 类中所有接口地址的前缀
public class UserController {
// @RequestMapping(value="loginGet", method= RequestMethod.GET)
@GetMapping("loginGet")
public String loginGet() {
return "登录成功";
}
// @RequestMapping(value="loginPost", method= RequestMethod.POST)
@PostMapping("loginPost") // 简便写法
public String loginPost(@RequestBody User user) { // 如果没用 @RequestBody,则获取结果为 null
log.info("username : " + user.getUsername());
log.info("password : " + user.getPassword());
return "登录成功:" + user.getUsername();
}
// 访问:http://localhost:8080/demo/userId/1/2
// @RequestMapping(value="userId/{userId}/{id}", method=RequestMethod.GET)
@GetMapping("getUser/{userid}/{id}")
public String loginUser1(@PathVariable("userid") Integer userid, @PathVariable("id") Integer id) {
log.info("userid : " + userid);
log.info("id : " + id);
return "userid: " + userid + " id: " + id;
}
// 访问:http://localhost:8080/demo/getUser?userid=1&id=2
// 访问:http://localhost:8080/demo/getUser?user=1&id=2,则 userid 值为 null
@GetMapping("getUser")
public String loginUser2(@RequestParam(value = "userid", required = false) Integer userid, // required=false:参数非必须传
@RequestParam("id") Integer id) {
log.info("userid : " + userid);
log.info("id : " + id);
return "userid: " + userid + " id: " + id;
}
@GetMapping("loginSuccess")
public ResponseEntity loginSuccess() {
User user = new User();
user.setUsername("creatorblue");
user.setPassword("admin123");
ResultResponse resultResponse = ResultResponse.builder().code("00").message("登录成功").data(user).build();
return ResponseEntity.status(HttpStatus.OK).body(resultResponse);
}
@GetMapping("loginFail")
public ResponseEntity loginFail() {
User user = new User();
user.setUsername("creatorblue");
user.setPassword("admin123");
ResultResponse resultResponse = ResultResponse.builder().code("02").message("登录失败").data(user).build();
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(resultResponse);
}
}
用更细化的@GetMapping、@PostMapping等系列注解替换了以前的@RequestMaping注解;另外,还使用@RequestBody替换了@ModelAttribute的参数绑定。
测试
http://localhost:8080/demo/loginSuccess
小结
至此,我们通过引入web模块(没有做其他的任何配置),就可以轻松利用Spring MVC的功能,以非常简洁的代码完成了对User对象的RESTful API的创建以及单元测试的编写。其中同时介绍了Spring MVC中最为常用的几个核心注解:@RestController,RequestMapping以及一些参数绑定的注解:@PathVariable,@RequestBody等。
后端接收前端数据的三种注解方式:
第一种:@RequestParam注解
- 作用: 将指定的请求参数赋值给方法中的形参。
- 接收形式: Get传参请求。
- 属性:
(1)value :绑定请求的参数名,默认绑定为同名的形参;
(2)required:是否必须,默认是true,表示请求中一定要有相应的参数,否则将报错;
(3)defaultValue:默认值,表示如果请求中没有接收到值时的默认值。 - 用法示例:
less
@GetMapping("/test")
public void test(@RequestParam(required = true)String name,@RequestParam(defaultValue = "20")Integer age) {
System.out.println("name:"+name+",age:"+age);
}
第二种:@PathVariable注解
- 作用: 接收请求路径中占位符的值。
- 接收形式: Get路径请求。
- 属性: value:String类型,绑定请求的参数名,默认绑定为同名的形参。
- 用法示例:
less
@GetMapping("/selectOne/{id}")
public void test(@PathVariable Integer id) {
System.out.println("id:"+id);
}
第三种:@RequestBody注解
- 作用: 接收前端传递的Json对象的字符串。
- 接收形式: Post请求。
- 用法示例:
less
@PostMapping("/test")
public void test(@RequestBody User user){
System.out.println("user:"+user);
}
实验实训
1、重点学习Spring MVC前端注解
2、重点复习RestFul接口命名规范
附录
SpringBoot 核心注解
注解 | 说明 |
---|---|
Component | 声明为 SpringBoot 的 bean |
Repository | 用于 dao 层的 bean |
Autowired | 用于向一个 bean 中注入其他 bean |
Service | 用于 service 层的 bean |
Configuration | 用于声明 SpringBoot 的配置文件类 |
Value("${key)") | 获取 SpringBoot 配置文件中的值 |
Bean | 声明其为 bean 实例,常和 Configuration 配合使用 |
SpringBoot Restful 接口实现
注解 | 说明 |
---|---|
SpringBootApplication | SpringBoot 主类,用来加载 SpringBoot 各种特性 |
RestController | SpringBoot 会转换返回值并自动将其写入 HTTP 响应 |
RequestMapping | 用于类和方法,在方法级别时,用于处理 HTTP 的各种方法 |
RequestBody | 将请求 Body 中的 json/xml 对象解析成该参数类型的 JavaBean 对象 |
PathVariable | 处理动态 URI,即 URI 的值可以作为控制器中处理方法的入参 |
Post/Put/Get/DeleteMapping | 在方法的级别上使用,在方法级别时,用于处理 HTTP 的各种方法 |
RequestParam | 处理 get 请求的参数 |