springboot 整合knife4j(绝对可用)1.9.6版~2.0.8版


1.情景展示

  开发接口供别人调用或者前后端分离后,前端调后端请求需要提供什么参数,会返回什么样的结果。如果一对一沟通的话,费时费力,写接口文档的话也比较麻烦。

2.效果展示

  现在使用knife4j就可以实现以下效果:

  点击调试按钮,就可以直接配置请求参数,发送请求啦

3 1.9.6版本配置

  这是1.9最后一个版本,要想实现这种效果,实现步骤如下:

  1.引入jar包

  只需要引入这一个jar包就可以了,无需其它jar包。    

  2.创建一个配置类,比如:Knife4jConfig

  3.导包

  4.添加注解 

  以上是三个注解,一个都不能少,在这里需要注意的一点就是:

  启用knif4j使用的注解是:@EnableSwaggerBootstrapUi,而不是@EnableKnife4j

  5.创建Docket对象,并注入到spring容器当中

  6.设置主页文档内容

   在配置文件类Knife4jConfig中添加以上两个方法即可。

4 2.0.4版本配置

  1.导包

<!--配置knife4j项目接口文档-->
<dependency>
    <groupId>com.github.xiaoymin</groupId>
    <artifactId>knife4j-spring-boot-starter</artifactId>
    <version>2.0.4</version>
</dependency>

  说明:2.0.2版本的,只需要把上面jar包的版本号改成2.0.2即可,下面的配置一模一样。

  只需要引入这一个jar包就可以了,无需其它jar包。    

  2.创建一个配置类,比如:Knife4jConfig(配置文件类最好创建一个config/conf包,方便统一管理)

 

import com.github.xiaoymin.knife4j.spring.annotations.EnableKnife4j;
import io.swagger.annotations.ApiOperation;
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.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

/**
 * 项目接口文档配置(swagger)
 * @description: 使用knife4j需要一个swagger的配置类
 * @author: Marydon
 * @date: 2020年08月11日 0011 9:22
 */
@Configuration
// 必须启用swagger
@EnableSwagger2
@EnableKnife4j
// swagger文档配置只在指定环境可访问(该注解的值对应的是application.yml文件中的spring.profiles.active的值)
// 支持使用!,比如:!prod表示非生产环境
// @Profile({"dev","test","jc"})
public class Knife4jConfig {
    /*
     * 创建连接的包信息
     * @param: 方法名称随便起,虽然它的名字会被作为Bean对象的名字注入spring容器
     * @date: 2020年08月11日 0011 9:51
     * @param: 
     * @return: springfox.documentation.spring.web.plugins.Docket 返回创建状况
     */
    @Bean
    public Docket defaultApi2() {
        return  new Docket(DocumentationType.SWAGGER_2) // 选择swagger2版本
                .useDefaultResponseMessages(false)
                // 接口文档的基本信息
                .apiInfo(apiInfo())
                .select()
                // 这里指定Controller扫描包路径(项目路径也行)
                // 方式一:配置扫描:所有想要在swagger界面统一管理的接口,都必须在此包下
                // .apis(RequestHandlerSelectors.basePackage("com.company.project.web.controller.entrance"))
                // 方式二:只有当方法上有@ApiOperation注解时,才能生成对应的接口文档
                .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
                // 路径使用any风格(指定所有路径)
                .paths(PathSelectors.any())
                .build();

    }

    /*
     * 设置文档信息主页的内容说明
     * @date: 2020年08月11日 0011 9:52
     * @param:
     * @return: springfox.documentation.service.ApiInfo 文档信息
     */
    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("接口项目 后台服务API接口文档")
                .description("服务相关接口(knife4j)")
                // 服务Url(网站地址)
                .termsOfServiceUrl("http://localhost:8080/")
                .contact(new Contact("Marydon",null,"marydon20170307@163.com"))
                .version("1.0")
                .build();
    }

}

  启动项目,访问:http://IP:端口号/程序名称/doc.html即可,显示主页。

5.注解基本用法

  @Api():用于类的说明,准确的来说用于controller,表示这个类是一个swagger资源

  对应的是:一个Controller

  注意:tags属性必须显式声明,否者无法修改小组的显示名称

  举例:

 

   实际效果:

  未生效(因为没有声明:tags=)

  @ApiOperation():用于方法的说明,表示这是一个HTTP请求

  对应的是controller里的方法

  2020-12-16

  这里需要注意的是:

  @PostMapping对应的post请求,反映到API上就是post请求;

  @GetMapping对应的get请求,反映到API上就是get请求;

  @RequestMapping如果没有指定具体请求方式

  API文档如下:

  它会给你生出7种不同的请求方式,API本身没错

  实际上,我们使用@RequestMapping的真实目的,也许是:想让该接口既支持get请求,也支持post请求,那我们可以做出限定。

  这样,就OK啦 

  有一个奇怪的地方就是:

  knife4j生成的所有接口方法,所对应的响应数据类型都是:*/*,当我在Mapping注解里指定可接受的数据类型后,API上却成了响应数据类型的值。

  请求的数据类型是不会受到影响的,knife4j是根据方法入参来自动判断请求的数据类型的,举个栗子:

  上面我们用的是@RequestBody,那knife4j就知道请求数据类型为:application/json;

  当我们改用@RequestParam时,它会识别为:application/x-www-form-urlencoded。

  等等,上面两种是我实际测试出来的,其它的识别方式就不得而知了。

  2020-12-17

  今天,发现:knife4j会将header和produces的值都塞到响应数据类型里面。比如:

@RequestMapping(value = "clear", method = {RequestMethod.GET, RequestMethod.POST}, headers = {"Accept=text/pain"}, produces = "text/html;charset=UTF-8")

  所以,当我们想要这里展示出具体的响应数据类型的话,在Mapping注解添加produces属性并设值即可。  

  @ApiOperationSupport():(knife4j增加特性)用于接口方法排序,作者信息描述等

  @ApiImplicitParams():参数列表说明

  如果不是用实体类接收入参的话,存在多个入参可以用该注解说明

  @ApiParam:对单个参数的说明

  如果不是用实体类接收入参的话,存在一个或者多个入参也可以用该注解进行逐个说明

  @ApiModel():用于描述一个数据模型的信息,即我们常用的实体、VO类、DTO类等描述

  在接口入参用实体类接收时,通常用该注解对实体类进行说明,一般与@ApiModelProperty结合使用,与上面两个参数注解达到的效果是一样的。

  @ApiModelProperty():用于描述数据模型的属性信息

  对应的是方法名的请求入参

  @ApiIgnore:自动生成接口说明时忽略,可用于类、方法、方法入参

  @ApiResponses:响应状态描述(在控制类下方,首个方法名上方)

  对应到文档上是: 

6 2.0.6以后的版本

  使用该版本,必须使用@EnableSwagger2WebMvc这一个注解。

  该配置类里的两个方法

  就可以合并成一个方法啦

@Bean(value = "defaultApi2")
public Docket defaultApi2() {
    Docket docket = new Docket(DocumentationType.SWAGGER_2) // 选择swagger2版本
            // 接口文档的基本信息
            .apiInfo(new ApiInfoBuilder()
                    .title("接口项目 后台服务API接口文档")
                    .description("服务相关接口(knife4j)")
                    // 服务Url(网站地址)
                    .termsOfServiceUrl("http://127.0.0.1:8080/")
                    .contact(new Contact("Marydon",null,"marydon20170307@163.com"))
                    .version("1.0")
                    .build())
            //分组名称,不配置的话,默认值为:default
            .groupName("2.X版本")
            .select()
            // 这里指定Controller扫描包路径(项目路径也行)
            // 方式一:配置扫描:所有想要在swagger界面统一管理的接口,都必须在此包下
            // .apis(RequestHandlerSelectors.basePackage("com.baidu.zhidao.web.controller.entrance"))
            // 方式二:只有当方法上有@ApiOperation注解时,才能生成对应的接口文档
            .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
            // 路径使用any风格(指定所有路径)
            .paths(PathSelectors.any())
            .build();
    return docket;
}

  PS:不合并也是可以哒。   

  说明:

  使用Knife4j2.0.6及以上的版本,Spring Boot的版本必须大于等于2.2.x 

  需要注意的是:

  当knife4j<=1.9.6时,它是knife4j的前身,叫做:swagger-bootstrap-ui,必须用注解@EnableSwaggerBootstrapUi+@EnableSwagger2;

  不仅支持swagger-bootstrap-ui,原始的swagger-ui还是可以使用的,访问地址:

  http://${host}:${port}/swagger-ui.html

  当2.0.0<=knife4j<=2.0.5时,必须用注解@EnableKnife4j+@EnableSwagger2;

  当2.0.6<=knife4j<=2.0.8时,必须使用注解@EnableSwagger2WebMvc。

  当knife4j>1.9.6时,已经不支持swagger-ui了。

7.文档设置访问权限控制

  一般情况下,我们在正式环境下是要屏蔽接口文档的,只有在非生产环境(比如:开发环境、测试环境)下才允许访问,如何实现?

  可在application.properties/application.yml文件中添加以下配置。

  禁用文档

  properties文件:knife4j.production=true

  yml文件如下:

  重启服务,此时,再次访问doc.html,将是这个样子:

  启用文档:将值改为false即可(表示的含义是:非生产环境)

  这样一来,在打包的时候,如果允许访问,就将其值改成false;否则,就改成true。

  这种方式不够智能,打包的时候,我们还需要记得改值,太麻烦了,还有更简单的一种。

  通过注解@Profile来实现

  可以配置多个访问环境,中间使用逗号隔开;

  也可以使用!,!prod,就表示只要profile的值不等于prod,就可以访问得到文档;

  @profile里的值对应的是主配置文件application.yml中spring.profiles.active的值,如下图所示:

  spring.profiles.active的值的值其实是很随意的,跟开发环境、生产环境、预演环境、生产环境等没有半毛钱关系,只不过是大家习惯于这样使用,方便区分罢了。

  按照这种方式,基本上就已经满足普通开发者的需求了,也相当于实现了动态配置。

  说明:

  如果采取这种方式,下面的值必须是false或者直接删掉该配置。

  然而这种方式对于我来说还是太傻了,随着公司产品的推广,一个地方会添加一个配置文件,每个地方又都有正式和测试之分;

  这样的话,每个地方测试的时候,我得改下配置启用;在正式上线的时候再禁用,太麻烦!怎么办,有没有一劳永逸的办法?

  通过在pom.xml中配置多个profile实现

  在properties标签添加自定义属性isProduction,名称随意,值是固定的:true/false

  在主配置文件application引入该标签的值即可

  说明:yml文件引入pom.xml的值使用@标签名@,properties文件引入pom.xml的值使用${标签名}

  这样,我在打包的时候,就不需要手动去修改production的值,而是通过切换环境通过maven插件,将对应的值塞到主配置文件中。

  说明:

  这种方式,适用于大量配置文件,且需要来回切换环境的需求;

  通过这种配置方式,就无需再配置@Profile注解了,否则就有点画蛇添足了。

8.文档通过密码访问

  通过上面,我们只能控制环境来间接控制文档是否可访问,只要你能访问该接口文档,那么别人也一样可以访问得到,还不够安全。

  如果有更高的安全需求,我们还可以为文档添加访问密码。

  这样,当我们再次访问该文档时,就需要输入用户名和密码才能访问啦。 

9.自定义Footer

  修改这个显示内容

  前提:knife4j>=2.0.8

  第一步:必须开启增强功能

  第二步:设置Footer

  第三步:修改knife4j的配置类,比如:我上面叫做Knife4jConfig.java

  注入对象:OpenApiExtensionResolver

// 自定义footer需要用到
@Resource
private OpenApiExtensionResolver openApiExtensionResolver;

  Docket增加扩展方法

new Docket(DocumentationType.SWAGGER_2)
                // 扩展属性(footer)
                .extensions(openApiExtensionResolver.buildSettingExtensions());

  效果展示:

10.分组排序

  2020-12-16

  文档上,每一项对应的是一个Controller,每一个controller相当于一个小组,有时候我们会想给它们排排顺序,怎么搞?

  要想实现这个个性化的需求,需要满足三个条件:

  第一,knife4j>=2.0.8;

  第二,使用注解@ApiSupport;

  说明:每个控制层的order值,必须大于0,且最好间隔10以上。 

  第三,开启增强功能。

  增强功能需要通过配置yml配置文件开启:

knife4j:
  enable: true

11.接口排序

  每个控制器可能会对外公开多个接口,多个接口如何自定义排序呢?

  使用注解@ApiOperationSupport;

  其它两个条件,同上,缺一不可。    

 

写在最后

  哪位大佬如若发现文章存在纰漏之处或需要补充更多内容,欢迎留言!!!

 相关推荐:

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM