Swagger更新为Knife4j

发布于 2021-10-23  84 次阅读


  • 项目介绍

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

一开始项目初衷是为了写一个增强版本的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包即可,因此分离前后端)

官方网站:https://doc.xiaominfo.com/knife4j/

  • 实战指南

1.引入jar包

     <!-- knife4j替换  swagger-->
            <dependency>
                <groupId>com.github.xiaoymin</groupId>
                <artifactId>knife4j-spring-boot-starter</artifactId>
                <version>3.0.2</version>
            </dependency>

2.配置对应的config加载类

package com.fasterres.framework.config;

import com.fasterres.framework.config.properties.SwaggerProperties;
import com.github.xiaoymin.knife4j.spring.annotations.EnableKnife4j;
import io.swagger.annotations.ApiOperation;
import io.swagger.models.auth.In;
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 java.util.ArrayList;
import java.util.List;

/**
 * Swagger 文档配置
 *
 * @author huangli 
 */
@Configuration
@EnableKnife4j
public class SwaggerConfig {

	@Autowired
	private SwaggerProperties swaggerProperties;

	/**
	 * 创建API
	 */
	@Bean
	public Docket createRestApi() {
		return new Docket(DocumentationType.OAS_30)
			.enable(swaggerProperties.getEnabled())
			// 用来创建该API的基本信息,展示在文档的页面中(自定义展示的信息)
			.apiInfo(apiInfo())
			// 设置哪些接口暴露给Swagger展示
			.select()
			// 扫描所有有注解的api,用这种方式更灵活
			.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
			// 扫描指定包中的swagger注解
			// .apis(RequestHandlerSelectors.basePackage("com.ruoyi.project.tool.swagger"))
			// 扫描所有 .apis(RequestHandlerSelectors.any())
			.paths(PathSelectors.any())
			.build()
			/* 设置安全模式,swagger可以设置访问token */
			.securitySchemes(securitySchemes())
			.securityContexts(securityContexts())
			.pathMapping(swaggerProperties.getPathMapping());
	}

	/**
	 * 安全模式,这里指定token通过Authorization头请求头传递
	 */
	private List<SecurityScheme> securitySchemes() {
		List<SecurityScheme> apiKeyList = new ArrayList<SecurityScheme>();
		apiKeyList.add(new ApiKey("Authorization", "Authorization", In.HEADER.toValue()));
		return apiKeyList;
	}

	/**
	 * 安全上下文
	 */
	private List<SecurityContext> securityContexts() {
		List<SecurityContext> securityContexts = new ArrayList<>();
		securityContexts.add(
			SecurityContext.builder()
				.securityReferences(defaultAuth())
				.operationSelector(o -> o.requestMappingPattern().matches("/.*"))
				.build());
		return securityContexts;
	}

	/**
	 * 默认的安全上引用
	 */
	private List<SecurityReference> defaultAuth() {
		AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
		AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
		authorizationScopes[0] = authorizationScope;
		List<SecurityReference> securityReferences = new ArrayList<>();
		securityReferences.add(new SecurityReference("Authorization", authorizationScopes));
		return securityReferences;
	}

	/**
	 * 添加摘要信息
	 */
	private ApiInfo apiInfo() {
		// 用ApiInfoBuilder进行定制
		SwaggerProperties.Contact contact = swaggerProperties.getContact();
		return new ApiInfoBuilder()
			// 设置标题
			.title(swaggerProperties.getTitle())
			// 描述
			.description(swaggerProperties.getDescription())
			// 作者信息
			.contact(new Contact(contact.getName(), contact.getUrl(), contact.getEmail()))
			// 版本
			.version(swaggerProperties.getVersion())
			.build();
	}
}

3.配置属性类

package com.fasterres.framework.config.properties;

import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * swagger 配置属性
 *
 * @author huangli
 */
@Data
@Component
@ConfigurationProperties(prefix = "swagger")
public class SwaggerProperties {

    /**
     * 验证码类型
     */
    private Boolean enabled;
	/**
	 * 设置请求的统一前缀
	 */
	private String pathMapping;
    /**
     * 验证码类别
     */
    private String title;
    /**
     * 数字验证码位数
     */
    private String description;
    /**
     * 字符验证码长度
     */
    private String version;

	/**
	 * 联系方式
	 */
    private Contact contact;

    @Data
	@NoArgsConstructor
	public static class Contact{

		/**
		 * 联系人
		 **/
		private String name;
		/**
		 * 联系人url
		 **/
		private String url;
		/**
		 * 联系人email
		 **/
		private String email;

	}

}

4.具体属性配置在application.yml文件中

# Swagger配置
swagger:
  # 是否开启swagger
  enabled: true
  # 请求前缀
  pathMapping: /dev-api
  # 标题
  title: '标题:${faster.name}后台管理系统_接口文档'
  # 描述
  description: '描述:faster项目的自定义接口开发文档knife4j..'
  # 版本
  version: '版本号: ${faster.version}'
  # 作者信息
  contact:
    name: **
    email: **@qq.com
    url: https://gitee.com/gallons_838/faster-res

前端地址映射

启动项目,访问knife4j路径 http://localhost:8080/doc.html

注意:访问时,如果提示 knife4j 文档异常,检查下自己的spring security配置拦截器是否开放了 knife4j 访问路径

.antMatchers("/doc.html").anonymous()//knife4j文档过滤

项目效果为

其他参考文档:实战SpringBoot系列 - 让Swagger跌下神坛的Knife4j使用详解 (baidu.com)