学成在线-内容管理2

一、知识点

1.JSR303校验

添加依赖

1
2
3
4
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>

添加校验

1
2
3
4
5
6
7
8
9
10
11
12
@Data
@ApiModel(value="AddCourseDto", description="新增课程基本信息")
public class AddCourseDto {

@NotEmpty(message = "课程名称不能为空")
@ApiModelProperty(value = "课程名称", required = true)
private String name;

@NotEmpty(message = "适用人群不能为空")
@Size(message = "适用人群内容过少",min = 10)
@ApiModelProperty(value = "适用人群", required = true)
private String users;

直接在定义字段时加入

1
2
3
4
5
@ApiOperation("新增课程接口")
@PostMapping("/course")
public CourseBaseInfoDto addCourseBase(@RequestBody @Validated AddCourseDto addCourseDto){
return courseBaseInfoService.createCourseBase(1232141425L,addCourseDto);
}

接着定义接口时加入参数

1
2
3
4
5
@ApiOperation("新增课程接口")
@PostMapping("/course")
public CourseBaseInfoDto addCourseBase(@RequestBody @Validated AddCourseDto addCourseDto){
return courseBaseInfoService.createCourseBase(1232141425L,addCourseDto);
}

定义异常拦截器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//处理JSR303数据校验异常
@ResponseBody
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public RestErrorResponse exception(MethodArgumentNotValidException e) {
BindingResult bindingResult = e.getBindingResult();

//存储错误信息
List<String> error = new ArrayList<>();
bindingResult.getFieldErrors().forEach((fieldError) -> {
String errorMessage = fieldError.getDefaultMessage();
error.add(errorMessage);
});

//转换为字串
String errorMessage = StringUtils.join(error,", ");
RestErrorResponse restErrorResponse = new RestErrorResponse(errorMessage);
return restErrorResponse;
}

分组校验

1
2
3
4
5
6
7
8
9
10
11
/**
* @description 校验分组
* @author Mr.M
* @date 2022/9/8 15:05
* @version 1.0
*/
public class ValidationGroups {
public interface Insert{};
public interface Update{};
public interface Delete{};
}

使用

1
2
3
@NotEmpty(message = "课程名称不能为空", groups={ValidationGroups.Insert.class})
@ApiModelProperty(value = "课程名称", required = true)
private String name;

接口这里设置组别

1
2
3
4
5
@ApiOperation("新增课程接口")
@PostMapping("/course")
public CourseBaseInfoDto addCourseBase(@RequestBody @Validated(ValidationGroups.Insert.class) AddCourseDto addCourseDto){
return courseBaseInfoService.createCourseBase(1232141425L, addCourseDto);
}

二、接口测试

1. httpclient

  • Swagger 的局限性:虽然 Swagger 作为在线接口文档工具很优秀,也能直接发起请求,但每次测试都需要打开浏览器,且最致命的是无法持久化保存测试数据和用例

  • HTTP Client 的优势:作为 IDEA 自带的强大工具,它允许开发者在 IDE 内直接发起 HTTP 请求,无需切换窗口。测试数据、参数和配置都可以作为代码保存下来,极大提高了测试和联调的效率。

  • 高版本 IDEA:通常已经默认内置了 HTTP Client 工具,直接创建 .http 文件即可使用。

  • 低版本 IDEA:如果没有自带该功能,需要在插件市场(Plugins)中搜索并安装 httpclient 插件。

2. 接口测试

在 IDEA 中编写请求并点击运行后,控制台会输出详细的响应信息,并自动将响应体保存为本地 JSON 文件:

发送 GET 请求:

1
2
### 查询课程列表接口
GET http://localhost:63040/course/list?pageNo=2&pageSize=10

执行结果与响应数据:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
HTTP/1.1 200 
Content-Type: application/json
Transfer-Encoding: chunked
Date: Wed, 07 Sep 2022 00:54:50 GMT
Keep-Alive: timeout=60
Connection: keep-alive

{
"items": [
{
"id": 88,
"companyId": 1232141425,
"companyName": null,
"name": "1",
"users": "1",
"tags": "1",
"mt": "1-1",
"grade": "204001",
"teachmode": "200002",
"description": "1",
"pic": "http://r3zc5rung.hd-bkt.clouddn.com/cb1b6038-ef68-4362-8c29-a966886d1dc5sakUiFHLb5sRFdIK",
"createDate": "2021-12-27 20:14:53",
"changeDate": "2021-12-27 20:28:58",
"status": 1
// ...省略部分空字段...
}
],
"counts": 14,
"page": 2,
"pageSize": 10
}

// 下方为 IDEA 自动生成的运行日志和文件保存提示
Response file saved.
> 2022-09-07T085450.200.json

Response code: 200; Time: 392ms (392 ms); Content length: 1916 bytes (1.92 kB)

3. 规范管理 .http 文件

  • 文档即测试用例.http 文件本质上就是测试用例文档。它可以被 Git 等版本控制系统管理,随着项目工程一起保存和提交。这样团队里的所有人都能复用这些测试数据,不用每次都手敲参数。
  • 统一存放目录:为了保持工程结构的清晰,建议在项目工程的根目录下单独创建一个文件夹(例如命名为 api-testshttp-requests),专门用来集中存放所有的 .http 测试文件。