导入依赖
Knife4j的依赖坐标如下:
1<dependency>
2 <groupId>com.github.xiaoymin</groupId>
3 <artifactId>knife4j-spring-boot-starter</artifactId>
4 <version>3.0.2</version>
5</dependency>
配置类
编写(或修改)配置类:
1@Configuration
2@EnableSwagger2 // 开启Swagger2
3@EnableKnife4j // 开启Knife4j
4public class WebMvcConfig extends WebMvcConfigurationSupport {
5
6 @Bean
7 public Docket createRestApi() {
8 // 设置文档类型
9 return new Docket(DocumentationType.SWAGGER_2)
10 .apiInfo(apiInfo())
11 .select()
12 // 设置Controller的包名
13 .apis(RequestHandlerSelectors.basePackage("com.linner.reggie.controller"))
14 .paths(PathSelectors.any())
15 .build();
16 }
17
18 /**
19 * API文档描述
20 * @return
21 */
22 private ApiInfo apiInfo() {
23 return new ApiInfoBuilder()
24 // 文档标题
25 .title("瑞吉外卖")
26 // 文档版本
27 .version("1.0")
28 // 文档描述
29 .description("瑞吉外卖接口文档")
30 .build();
31 }
32
33 /**
34 * 设置静态资源映射
35 * <p>放行静态页面资源</p>
36 * @param registry
37 */
38 @Override
39 public void addResourceHandlers(ResourceHandlerRegistry registry) {
40 // API文档的静态资源映射
41 registry.addResourceHandler("doc.html")
42 .addResourceLocations("classpath:/META-INF/resources/");
43 registry.addResourceHandler("/webjars/**")
44 .addResourceLocations("classpath:/META-INF/resources/webjars/");
45 }
46}
资源放行
放行文档静态页面请求。必须确保以下静态资源路径可以被访问,不被拦截:
1/doc.html
2/webjars/**
3/swagger-resources
4/v2/api-docs
API 文档注解
| 注解 | 说明 |
|---|---|
@Api |
用在请求的类上(例如Controller,使用tags元素指定文档的标签。 |
@ApiModel |
用在类上(例如实体类),表示一个返回响应数据的信息。 |
@ApiModelProperty |
用在属性上,描述响应类(实体类)的属性。 |
@ApiOperation |
用在请求的方法上,说明方法的用途、作用。 |
@ApiImplicitParams |
用在请求的方法上,表示一组参数说明。 |
@ApiImplicitParam |
用在@ApiImplicitParams注解中,指定一个请求参数的各个方面。如果只用说明一个参数的话, @ApiImplicitParam可以单独用在方法上。 |
注意:@ApiImplicitParam不能对实体类进行定义,否则访问API文档时/v2/api-docs会出现接口异常(500状态码)。
示例
标识响应数据信息:
1/**
2 菜品
3 */
4@Data
5@ApiModel("菜品") // 标识实体类的名称
6public class Dish implements Serializable {
7
8 private static final long serialVersionUID = 1L;
9
10 @ApiModelProperty("菜品ID") // 标识实体类属性的名称
11 private Long id;
12
13 //菜品名称
14 @ApiModelProperty("菜品名称") // 标识实体类属性的名称
15 private String name;
16
17 //菜品分类id
18 @ApiModelProperty("菜品分类ID") // 标识实体类属性的名称
19 private Long categoryId;
20
21 //菜品价格
22 @ApiModelProperty("菜品价格") // 标识实体类属性的名称
23 private BigDecimal price;
24
25 //商品码
26 @ApiModelProperty("商品码") // 标识实体类属性的名称
27 private String code;
28
29 //图片
30 @ApiModelProperty("菜品图片") // 标识实体类属性的名称
31 private String image;
32
33 //描述信息
34 @ApiModelProperty("描述信息") // 标识实体类属性的名称
35 private String description;
36
37 //0 停售 1 起售
38 @ApiModelProperty("商品状态") // 标识实体类属性的名称
39 private Integer status;
40
41 //顺序
42 @ApiModelProperty("展示顺序") // 标识实体类属性的名称
43 private Integer sort;
44
45 /* ... */
46}
标识请求类:
1/**
2 * 菜品管理
3 */
4@RestController
5@RequestMapping("/dish")
6@Api(tags = "菜品管理")
7public class DishController {
8
9 @Autowired
10 private DishService dishService;
11 @Autowired
12 private DishFlavorService dishFlavorService;
13 @Autowired
14 private CategoryService categoryService;
15 @Autowired
16 private RedisTemplate redisTemplate;
17
18 /**
19 * 新增菜品
20 * @param dishDto
21 * @return
22 */
23 @PostMapping
24 @ApiOperation("新增菜品") // 标识API方法,对API请求进行说明
25 public R<String> save(@RequestBody DishDto dishDto) {
26 // 清理某个分类下面的菜品缓存
27 String key = this.getRedisKey(dishDto);
28 redisTemplate.delete(key);
29
30 dishService.saveWithFlavor(dishDto);
31 return R.success("新增菜品成功"); // 返回一个请求成功的响应体信息
32 }
33
34 /**
35 * 菜品信息分页查询
36 * @param page
37 * @param pageSize
38 */
39 @GetMapping("/page")
40 @ApiOperation("菜品信息分页查询") // 标识API方法,对API请求进行说明
41 @ApiImplicitParams({ // 标识API方法,对API请求参数进行说明
42 /**
43 * @ApiImplicitParam 对请求参数进行具体的说明,它的属性有:
44 * - name:标识请求参数的名称,与API方法的参数名对应
45 * - value:对name对应的参数进行说明
46 * - required:对name对应的参数是否为必须的请求参数进行说明
47 * - true:值为true表示该参数是请求时必须携带的
48 * - false:值为false表示在进行请求时,可以不必携带该参数
49 */
50 @ApiImplicitParam(name = "page", value = "页码", required = true),
51 @ApiImplicitParam(name = "pageSize", value = "每页展示数据条数", required = true),
52 @ApiImplicitParam(name = "name", value = "要搜索的菜品名称")
53 })
54 public R<Page> page(int page, int pageSize, String name) {
55 // 构造分页构造器对象
56 Page<Dish> pageInfo = new Page<>(page, pageSize);
57 Page<DishDto> dishDtoPage = new Page<>();
58
59 // 条件构造器
60 LambdaQueryWrapper<Dish> queryWrapper = new LambdaQueryWrapper<>();
61 // 添加过滤条件
62 queryWrapper.like(name != null, Dish::getName, name);
63 // 添加排序条件(降序排序)
64 queryWrapper.orderByDesc(Dish::getUpdateTime);
65 // isDeleted不为1(为1表示被删除)
66 queryWrapper.ne(Dish::getIsDeleted, 1);
67
68 // 执行分页查询
69 dishService.page(pageInfo, queryWrapper);
70
71 // 对象拷贝
72 BeanUtils.copyProperties(pageInfo, dishDtoPage, "records");
73
74 List<Dish> records = pageInfo.getRecords();
75 List<DishDto> list = records.stream().map((item) -> {
76 DishDto dishDto = new DishDto();
77
78 BeanUtils.copyProperties(item, dishDto);
79
80 Long categoryId = item.getCategoryId(); // 分类id
81 Category category = categoryService.getById(categoryId); // 根据id查询分类对象
82 if (category != null) {
83 String categoryName = category.getName();
84 dishDto.setCategoryName(categoryName);
85 }
86 return dishDto;
87 }).collect(Collectors.toList());
88
89 dishDtoPage.setRecords(list);
90
91 return R.success(dishDtoPage);
92 }
93
94 /**
95 * 根据id查询菜品全部信息(包括口味)
96 * @param id
97 */
98 @GetMapping("/{id}")
99 @ApiOperation("根据id查询菜品全部信息(包括口味)")
100 // 如果方法仅有一个参数,可以使用一个@ApiImplicitParam标识,无需使用@ApiImplicitParams
101 @ApiImplicitParam(name = "id", value = "要查询的菜品ID", required = true)
102 public R<DishDto> get(@PathVariable Long id) {
103
104 DishDto dishDto = dishService.getByIdWithFlavor(id);
105
106 return R.success(dishDto);
107 }
108}
更多详细用法,请参考:瑞吉外卖项目 Knife4j 笔记
评论