9、接口文档:Swagger与knife4j

Swagger

  接口文档对于前后端开发人员都十分重要。尤其近几年流行前后端分离后接口文档又变成重中之重。接口文档固然重要,但是由于项 目周期等原因后端人员经常出现无法及时更新,导致前端人员抱怨接 口文档和实际情况不一致。

很多人员会抱怨别人写的接口文档不规范,不及时更新。当时当 自己写的时候确实最烦去写接口文档。这种痛苦只有亲身经历才会牢 记于心。

如果接口文档可以实时动态生成就不会出现上面问题。

Swagger 可以完美的解决上面的问题。

Swagger 简介:


  Swagger 是一套围绕 Open API 规范构建的开源工具,可以帮助设 计,构建,记录和使用 REST API。

Swagger 工具包括的组件:

  • Swagger Editor :基于浏览器编辑器,可以在里面编写 Open API规范。类似 Markdown 具有实时预览描述文件的功能。
  • Swagger UI:将 Open API 规范呈现为交互式 API 文档。用可视化UI 展示描述文件。
  • Swagger Codegen:将 OpenAPI 规范生成为服务器存根和客户端 库。通过 Swagger Codegen 可以将描述文件生成 html 格式和 cwiki 形 式的接口文档,同时也可以生成多种言语的客户端和服务端代码。

Swagger Inspector:和 Swagger UI 有点类似,但是可以返回更多 信息,也会保存请求的实际参数数据。

Swagger Hub:集成了上面所有项目的各个功能,你可以以项目 和版本为单位,将你的描述文件上传到 Swagger Hub 中。在 Swagger Hub 中可以完成上面项目的所有工作,需要注册账号,分免费版和收费版。

使用 Swagger,就是把相关的信息存储在它定义的描述文件里面(yml 或 json 格式),再通过维护这个描述文件可以去更新接口文档, 以及生成各端代码。

Swagger集成

1、新建springbootweb项目导入maven依赖

<!--swagger依赖-->
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger-ui</artifactId>
    <version>2.9.2</version>
</dependency>
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger2</artifactId>
    <version>2.9.2</version>
</dependency>

2、创建Swagger配置:config/SwaggerConfig.java

 1 import org.springframework.context.annotation.Configuration;
 2 import springfox.documentation.swagger2.annotations.EnableSwagger2;
 3 
 4 /**
 5  * @author zhangzhixi
 6  */
 7 @Configuration
 8 @EnableSwagger2 // 开启Swagger2
 9 public class SwaggerConfig {
10 
11 }

3、测试访问

访问:localhost:8080/swagger-ui.html

 swagger首页DIY:

在SwaggerConfig进行如下配置即可自定义Swagger配置

 1 package com.zhixi.config;
 2 
 3 import org.springframework.context.annotation.Bean;
 4 import org.springframework.context.annotation.Configuration;
 5 import springfox.documentation.service.ApiInfo;
 6 import springfox.documentation.service.Contact;
 7 import springfox.documentation.spi.DocumentationType;
 8 import springfox.documentation.spring.web.plugins.Docket;
 9 import springfox.documentation.swagger2.annotations.EnableSwagger2;
10 
11 import java.util.ArrayList;
12 
13 /**
14  * @author zhangzhixi
15  */
16 @Configuration
17 @EnableSwagger2 // 开启Swagger2
18 public class SwaggerConfig {
19 
20     // 配置Swagger
21     @Bean
22     public Docket docket() {
23         // 返回docket的bean实例
24         return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo());
25     }
26 
27     // 配置swagger的信息-api-info
28     private ApiInfo apiInfo() {
29         // 作者说明
30         Contact contact = new Contact("志喜", "https://www.cnblogs.com/zhangzhixi", "1820712542@qq.com");
31         return new ApiInfo(
32                 "志喜的SwaggerAPI文档",
33                 "人生没有白走的路~",
34                 "1.0",
35                 "urn:tos",
36                 contact,
37                 "Apache 2.0",
38                 "http://www.apache.org/licenses/LICENSE-2.0",
39                 new ArrayList());
40     }
41 }

Swagger扫描接口:


// 配置Swagger
@Bean
public Docket docket() {
    // 返回docket的bean实例
    return new Docket(DocumentationType.SWAGGER_2)
            .apiInfo(apiInfo())
            .enable(true)//是否启用Swagger,false则不启用
            .select()
            //RequestHandlerSelectors,配置要扫描接口的方式
            //basePackage,指定扫描包
            //.apis(RequestHandlerSelectors.any()),扫描全部
            //.apis(RequestHandlerSelectors.none()),不扫描
            //withMethodAnnotation(GetMapping.class)) //扫描类上的注解
            //withClassAnnotation(GetMapping.class)) //扫描方法上的注解
            .apis(RequestHandlerSelectors.basePackage("com.zhixi.controller"))
            //Path过滤路径
            //.paths(PathSelectors.ant("/com/**"))
            .build();
}

实现开发环境中使用Swagger,运行上线环境中不使用Swagger:

 // 配置Swagger
 @Bean
 public Docket docket(Environment environment) {
     //设置要显示的Swagger环境
     Profiles profiles = Profiles.of("dev", "test");
     //获取项目的环境:判断是否处在自己设定的环境中
     boolean flag = environment.acceptsProfiles(profiles);
     // 返回docket的bean实例
     return new Docket(DocumentationType.SWAGGER_2)
             .apiInfo(apiInfo())
             .enable(flag)//是否启用Swagger,false则不启用
}

分组以及注释:

分组管理:

  通过groupName("")配置多个Docket,(在多人开发中,每个开发者配置一个自己的Swagger,方便管理)

@Bean
public Docket docket1() {
    return new Docket(DocumentationType.SWAGGER_2)
            .groupName("test1");
}
@Bean
public Docket docke2() {
    return new Docket(DocumentationType.SWAGGER_2)
            .groupName("test2");
}
@Bean
public Docket docket3() {
    return new Docket(DocumentationType.SWAGGER_2)
            .groupName("test3");
}

Swagger常用注解:

controller中:

 @Api(tags = "请求控制类")  // 给controller类加注释

 @ApiOperation("用户赋值请求")  //给controller请求加注释

pojo实体类中:

  @ApiModel("用户类")  // 标注类的信息

 @ApiModelProperty("用户名")  // 标注属性信息

public String username;

swagger 测试:

  controller请求:

 @ApiOperation("用户赋值请求")
 @RequestMapping("/user")
 public User getUser1(User user) {
     return user;
 }

knife4j

官方地址:https://doc.xiaominfo.com/knife4j/

 项目介绍:

Knife4j的前身是swagger-bootstrap-ui,前身swagger-bootstrap-ui是一个纯swagger-ui的ui皮肤项目

一开始项目初衷是为了写一个增强版本的swagger的前端ui,但是随着项目的发展,面对越来越多的个性化需求,不得不编写后端Java代码以满足新的需求,在swagger-bootstrap-ui的1.8.5~1.9.6版本之间,采用的是后端Java代码和Ui都混合在一个Jar包里面的方式提供给开发者使用.这种方式虽说对于集成swagger来说很方便,只需要引入jar包即可,但是在微服务架构下显得有些臃肿。

因此,项目正式更名为knife4j,取名knife4j是希望她能像一把匕首一样小巧,轻量,并且功能强悍,更名也是希望把她做成一个为Swagger接口文档服务的通用性解决方案,不仅仅只是专注于前端Ui前端.

swagger-bootstrap-ui的所有特性都会集中在knife4j-spring-ui包中,并且后续也会满足开发者更多的个性化需求.

主要的变化是,项目的相关类包路径更换为com.github.xiaoymin.knife4j前缀,开发者使用增强注解时需要替换包路径

后端Java代码和ui包分离为多个模块的jar包,以面对在目前微服务架构下,更加方便的使用增强文档注解(使用SpringCloud微服务项目,只需要在网关层集成UI的jar包即可,因此分离前后端)

如何使用:

注解 说明
@Api 用在请求类上面,列如Controller,表示对类的说明
@ApiModel 用在类上,通常是实体类,表示一个返回响应数据的信息
@ApiModelProperty 用在属性上面,描述响应类的属性
@ApiOperation 用在请求方法上,说明方法用途、作用
@ApiImplicitParams 用在请求方法上,表示一组参数说明
@ApiImplicitParam 用在@ApiImplicitParams注解中,指定一个请求参数的各个方面

1、添加配置类,需要在配置类上面添加两个注解:@EnableSwagger2和@EnableKnife4j

import com.github.xiaoymin.knife4j.spring.annotations.EnableKnife4j;
import com.zhixi.common.JacksonObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

import java.util.List;

/**
 * @ClassName WebMvcConfig
 * @Author zhangzhixi
 * @Description
 * @Date 2022-7-8 10:47
 * @Version 1.0
 */
@Slf4j
@Configuration
// 接口文档注解
@EnableSwagger2
@EnableKnife4j
public class WebMvcConfig extends WebMvcConfigurationSupport {
    /**
     * 设置静态资源映射
     *
     * @param registry 注册器
     */
    @Override
    protected void addResourceHandlers(ResourceHandlerRegistry registry) {
        log.info("开始进行静态资源映射。。。");
        //访问路径,映射到真实的路径(映射的真实路径末尾必须添加斜杠`/`)
        registry.addResourceHandler("/backend/**").addResourceLocations("classpath:/backend/");
        registry.addResourceHandler("/front/**").addResourceLocations("classpath:/front/");
        // 设置接口文档的访问路径
        registry.addResourceHandler("doc.html").addResourceLocations("classpath:/META-INF/resources/");
        registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
    }


    /**
     * 接口文档配置
     *
     * @return Docket
     */
    @Bean
    public Docket createRestApi() {
        // 文档类型
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .select()
                // 扫描接口所在的包
                .apis(RequestHandlerSelectors.basePackage("com.zhixi.controller"))
                .paths(PathSelectors.any())
                .build();
    }

    /**
     * 接口文档配置
     *
     * @return ApiInfo
     */
    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("瑞吉外卖")
                .version("1.0")
                // 作者
                .contact(new Contact("zhangzhixi", "www.cnblogs.com/zhangzhixi", "1820712542@qq.com"))
                .description("瑞吉外卖接口文档")
                .build();
    }
}

2、在接口/方法/实体类添加对应注解

这里就不贴图片了,直接放Gitee地址,参考吧,只做了Dish相关的文档说明:

DishController:https://gitee.com/-/ide/project/zhang-zhixi/ruiji-takeout/edit/master/-/src/main/java/com/zhixi/controller/DishController.java

Dish:https://gitee.com/-/ide/project/zhang-zhixi/ruiji-takeout/edit/master/-/src/main/java/com/zhixi/pojo/Dish.java

3、测试访问:

localhost:8080/doc.html

posted @ 2021-01-30 13:45  Java小白的搬砖路  阅读(651)  评论(0编辑  收藏  举报