Swagger-knife4j攻略(国产超强swagger文档)

swagger-knife4j测试文档完整攻略

1.swagger是什么?

swagger 是一个 api 文档维护组织,后来成为了 Open API 标准的主要定义者;

对于开发者来说,swagger是帮助后端开发人员在开发/测试环境下生成接口测试页面功能的注解;

大多数项目用的是swagger2标准OpenApi2的规范,最新的规范是swagger3的OpenApi3规范;

提到swagger,那么SpringFox和SpringDoc作为实现swagger规范的佼佼者,自然被广大后端人员大量使用,目前SpringFox已经支持swagger3的注解(swagger2也可使用),而SpringDoc已经进化成仅支持swagger3的注解了。

但是对于国人来说SpringFox和SpringDoc实现的ui界面并没有多友好,用到极致也不过是个懒得写测试用例的框架罢了,前端人员看这个ui界面可以说很抓狂,后端人员也很苦恼,我这swagger都维护好了,怎么前端就看不懂了,怎么项目经理还要我再写个接口文档?

主要原因是:英文烂、ui界面没有区分度、无法生成静态的接口文档

那么国人应该用什么框架来解决这些烦恼呢?knife4j

2.什么是knife4j?

Knife4j是为Java MVC框架集成Swagger生成Api文档的增强解决方案,前身是swagger-bootstrap-ui,取名kni4j是希望她能像一把匕首一样小巧,轻量,并且功能强悍!

简单来说,Knife4j是遵循swagger2规范,集成springFox并增强的前后端一体化框架

开源地址:https://gitee.com/xiaoym/knife4j

文档地址:https://doc.xiaominfo.com/knife4j/documentation/

截一张图展示一下:

Swagger-knife4j攻略(国产超强swagger文档)_第1张图片

  • 把SpringFox原来的上下结构变成了左右导航栏结构,清晰
  • 具有接口文档的生成功能(再也不要浪费时间再写一遍接口文档了)
  • 具有前端页面添加统一Header的功能(不用在后端配置文件里写Header了)
  • 每个api具备一个小型的postman功能(比SpringFox强多了)

3.通用使用教程

本教程使用的注解全部为swagger2的注解,也就是Api开头的注解,比如@ApiOperation("注册")@Api(tags = "登陆控制"),如果已存在的项目用的是swagger3的注解,请继续使用SpringDoc哈。

仅介绍最通用的使用教程,最常用的swagger实现框架,大概就是SpringFox了,而knife4j是包含SpringFox的,需要用knife4j就要更换掉原SpringFox依赖。

1.依赖:

        





        <dependency>
            <groupId>com.github.xiaoymingroupId>
            <artifactId>knife4j-spring-boot-starterartifactId>
            
            <version>3.0.3version>
        dependency>
  • 已有springfox的项目注释掉再引入
  • 没有springfox的项目直接引入

2.通用springboot-swagger2配置文件:

import com.github.xiaoymin.knife4j.spring.extension.OpenApiExtensionResolver;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.*;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.contexts.SecurityContext;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

import java.util.ArrayList;
import java.util.List;

/**
 * swagger2配置
 *
 * @author huang cheng
 * 2021/8/13
 */
@Configuration
@EnableSwagger2
public class Swagger2Config {

    /*引入Knife4j提供的扩展类*/
    private final OpenApiExtensionResolver openApiExtensionResolver;

    @Autowired
    public Swagger2Config(OpenApiExtensionResolver openApiExtensionResolver) {
        this.openApiExtensionResolver = openApiExtensionResolver;
    }

    private final static String groupName = "cheng";//组群名称

    private final static String headerName = "Authorization";//需要swagger每次调接口前携带的头信息的key
    //private final static String headerName2 = "test";//如果要多个请求头信息,自行解放注释

    @Bean
    public Docket createRestApi() {
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())//文档信息
                .groupName(groupName)//组群名称
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.cheng.authonlytoken.controller"))//需要扫描的api所在目录
                .paths(PathSelectors.any())//匹配全部地址路径
                .build()
                .securitySchemes(securitySchemes())//配置安全方案
                .securityContexts(securityContexts())//配置安全方案所实现的上下文
                .extensions(openApiExtensionResolver.buildExtensions(groupName))//赋予插件体系
                ;
    }

    private List<SecurityScheme> securitySchemes() {
        List<SecurityScheme> apiKeyList = new ArrayList<>();
        //配置header头1
        ApiKey token_access = new ApiKey(headerName, headerName, "header");
        apiKeyList.add(token_access);
        //配置header头2
        //ApiKey token_access2 = new ApiKey( headerName2, headerName2, "header");
        //apiKeyList.add(token_access2);
        return apiKeyList;
    }

    private List<SecurityContext> securityContexts() {
        List<SecurityContext> securityContextList = new ArrayList<>();
        List<SecurityReference> securityReferenceList = new ArrayList<>();
        //为每个api添加请求头
        securityReferenceList.add(new SecurityReference(headerName, scopes()));
        //以此类推
        //securityReferenceList.add(new SecurityReference(headerName2, scopes()));
        securityContextList.add(SecurityContext
                .builder()
                .securityReferences(securityReferenceList)
                .forPaths(PathSelectors.any())
                .build()
        );
        return securityContextList;
    }

    private AuthorizationScope[] scopes() {
        return new AuthorizationScope[]{new AuthorizationScope("global", "accessAnything")};//作用域为全局
    }

    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("swagger2文档")
                .description("更多精彩博客请关注:https://blog.csdn.net/qq_42495847?spm=1000.2115.3001.5343")
                .termsOfServiceUrl("https://blog.csdn.net/qq_42495847?spm=1000.2115.3001.5343")
                .contact(new Contact("cheng", "https://blog.csdn.net/qq_42495847?spm=1000.2115.3001.5343", "[email protected]"))
                .version("1.0")
                .build();
    }

}
  • 该配置实现了添加一个全局的header名为Authorization,并让所有扫描到的api携带这个header
  • 该配置实现了自定义的文档信息(ApiInfo)

3.如果有拦截器,请放行以下地址:

    /**
     * 放行Swagger
     */
    public static final String[] SWAGGER_WHITELIST = {
            "/swagger-ui.html/**",
            "/swagger-ui/**",
            "/swagger-resources/**",
            "/v2/api-docs",
            "/v3/api-docs",
            "/v3/api-docs/swagger-config",
            "/webjars/**",
            "/doc.html",
    };

最后在生成环境yml配置文件中加上配置:

knife4j:
  # 开启增强配置 
  enable: true
 # 开启生产环境屏蔽
  production: true
  • production: true时就访问不了swagger了
  • 测试环境改成 production: false

4.配置每个接口的swagger注解信息

swagger2常用注解:

常用注解

swagger2 swagger3 注解位置
@Api(tags = “接口类描述”) @Tag(tags = “接口类描述”) Controller 类上
@ApiOperation(“接口方法描述”) @Operation(summary =“接口方法描述”) Controller 方法上
@ApiImplicitParams @Parameters Controller 方法上
@ApiImplicitParam @Parameter(description=“参数描述”) Controller 方法上 @Parameters 里
@ApiParam(“参数描述”) @Parameter(description=“参数描述”) Controller 方法的参数上
@ApiIgnore @Parameter(hidden = true) 或 @Operation(hidden = true) 或 @Hidden -
@ApiModel(description = “dto类描述”) @Schema(description = “dto类描述”) DTO类上
@ApiModelProperty(“属性描述”) @Schema(description = “属性描述”) DTO属性上

还是从前swagger2的味道,示例如下:

controller:

/**
 * 用户登录控制
 * @author huang cheng
 * 2021/8/11
 */
@Api(tags = "登陆控制")
@RestController
@RequestMapping("/auth")
public class LoginController {

    @Resource
    private LoginService loginService;

    @ApiOperation("注册")
    @PostMapping("/register")
    public CResponse<TokenVo> register(@RequestBody @Valid RegisterDto registerDto){
        return loginService.register(registerDto);
    }

    /**
     * 微信授权成功后调用该方法 获取token
     * @param loginDto 传入该用户可获取到的用户信息
     * @return token 放到Header中的Authorization作为值
     */
    @ApiOperation("得到token")
    @PostMapping("/getToken")
    public CResponse<TokenVo> getToken(@RequestBody @Valid LoginDto loginDto){
        return loginService.getToken(loginDto);
    }

    /**
     * 得到当前token中包含的用户信息
     * @return 用户信息
     */
    @ApiOperation("得到当前token中包含的用户信息")
    @PostMapping("/getUserInfo")
    public CResponse<UserInfo> getUserInfo(HttpServletRequest request){
        String token = request.getHeader("Authorization");
        if (StringUtils.isBlank(token)){
            throw new CommonException("token为空");
        }
        return loginService.getUserInfo(token);
    }
}

pojo:

/**
 * 登陆参数
 * @author huang cheng
 * 2021/8/11
 */
@ApiModel("登陆参数")
@Data
public class LoginDto {

    @ApiModelProperty("登录类型")
    @NotBlank(message = "登录类型不能为空")
    private String identityType;

    @ApiModelProperty("标识-账号")
    @NotBlank(message = "账号不能为空")
    private String identifier;

    @ApiModelProperty("密码凭证")
    @NotBlank(message = "密码凭证不能为空")
    private String credential;
}

5.配置完成后访问 域名/{contextPath}/doc.html

比如我访问localhost:8080/doc.html,即可进入好看的knife4j的ui界面了

6.配置统一的认证请求头

一般接口都至少戴个token来证明自己是安全的请求,通用的配置文件中已经配置了请求头Authorization,可以在Authorize界面看到

Swagger-knife4j攻略(国产超强swagger文档)_第2张图片

  • 配置后点接口就可以发现请求头都带上key和value
  • 没带上的话关闭接口页面,重新点进去

配置后api的调试界面自动带上该请求头的key和value

Swagger-knife4j攻略(国产超强swagger文档)_第3张图片

7.离线文档功能

在文档管理-离线文档中,可下载四种格式的接口文档:markdown、HTML、word、openapi

Swagger-knife4j攻略(国产超强swagger文档)_第4张图片

示例:

Swagger-knife4j攻略(国产超强swagger文档)_第5张图片

已经比自己写的接口文档还要好看和详细了

如果是多人合作项目,不想生成其他人的api信息,使用复制文档功能:

Swagger-knife4j攻略(国产超强swagger文档)_第6张图片

  • 会复制当前api的markdown文档

4.进阶使用方法

前往官方文档查看:

文档地址:https://doc.xiaominfo.com/knife4j/documentation/

你可能感兴趣的:(swagger,swagger2,swagger3,knife4j)