导入依赖

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 笔记