对于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包即可,因而拆散前后端)

knife4j沿用swagger-bootstrap-ui的版本号,第1个版本从1.9.6开始,对于应用办法,请参考文档(摘自 knife4j 官网介绍)。

引入knife4j

knife4j 次要的版本根本如下所示

版本阐明
1.9.6蓝色皮肤格调,开始更名,减少更多后端模块
2.0~2.0.5Ui重写,底层依赖的springfox框架版本是2.9.2
2.0.6~层springfox框架版本升级知2.10.5,OpenAPI标准是v2
3.0~底层依赖springfox框架版本升级至3.0.3,OpenAPI标准是v3

咱们引入的是3.0.3,因为3.x只公布了一个版本,稳定性可能存在肯定的问题,如果你想最求稳固,那么举荐你应用 2.x,因为我这里只是demo展现,加上我本人喜爱新版本,所以我这里应用了3.0.3,提前帮大家猜猜坑。

<dependency>    <groupId>com.github.xiaoymin</groupId>    <artifactId>knife4j-spring-boot-starter</artifactId>    <version>3.0.3</version></dependency>

留神

  • knife4j 曾经引入了 springfox,所以在应用的时候无需再次引入
    springfox,否则有可能会导致版本抵触,如果你在网关聚合时,必须禁用 knife4j 的加强性能。
  • 应用Knife4j2.0.6及以上的版本,Spring Boot的版本必须大于等于2.2.x

创立 Swagger 配置依赖

package com.ymy.notes.config.kinfe4j;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.Contact;import springfox.documentation.spi.DocumentationType;import springfox.documentation.spring.web.plugins.Docket;import springfox.documentation.swagger2.annotations.EnableSwagger2;@Configuration@EnableSwagger2public class Knife4jConfiguration {    @Bean(value = "defaultApi2")    public Docket defaultApi2() {        String groupName="3.X版本";        Docket docket=new Docket(DocumentationType.OAS_30)                .apiInfo(new ApiInfoBuilder()                        .title("这是knife4j API ")                        .description("# 这里记录服务端所有的接口的入参,出参等等信息")                        .termsOfServiceUrl("http://yaomaoyang.com")                        .contact(new Contact("顺流星","http://yaomaoyang.com","361426201@qq.com"))                        .version("3.0")                        .build())                //分组名称                .groupName(groupName)                .select()                //这里指定Controller扫描包门路                .apis(RequestHandlerSelectors.basePackage("com.ymy.notes.controller"))                .paths(PathSelectors.any())                .build();        return docket;    }}

这里须要留神一点,如果你应用的是 2.x,那么须要将 @EnableSwagger2 替换成 @EnableSwagger2WebMvc, 因为 @EnableSwagger2 是在 3.x 才引入的注解,并且将@EnableSwagger2WebMvc 设置为不举荐应用

配置我的项目名和端口信息

server:  port: 8818spring:  application:    name: notes

创立一个简略的 RESTful 接口

package com.ymy.notes.controller;import io.swagger.annotations.Api;import io.swagger.annotations.ApiImplicitParam;import io.swagger.annotations.ApiOperation;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestParam;import org.springframework.web.bind.annotation.RestController;@RestController@RequestMapping(value = "/test")@Api(tags = "测试swagger")public class Knife4jTestController {    @GetMapping(value = "/hello")    @ApiImplicitParam(name = "name",value = "姓名",required = true)    @ApiOperation("测试接口")    public String test(@RequestParam("name") String name){        return "hello "+name+", I am  meimei han";    }}

启动我的项目

如果你在启动我的项目的时候抛出:Failed to start bean 'documentationPluginsBootstrapper'; nested exception is java.lang.NullPointerException

千万不要慌,那是因为你的 springboot 版本太高,应该是 2.6.x,因为Springfox应用的门路匹配是基于AntPathMatcher,而Spring Boot 2.6.X应用的是PathPatternMatcher,所以将MVC的门路匹配规定改成 AntPathMatcher,在配置文件中退出如下参数即可(如果没有报错,能够跳过这个环节)

spring:  mvc:    pathmatch:      # Springfox应用的门路匹配是基于AntPathMatcher的,而Spring Boot 2.6.X应用的是PathPatternMatcher      # 所以须要配置此参数      matching-strategy: ant_path_matcher

启动胜利之后,在浏览器中拜访:http://127.0.0.1:8818/doc.html(ip+端口+/doc.html)。
如果看到上面的画面,阐明knife4j曾经配置胜利。



到此为止,knife4j 曾经完满的运行起来了,后端人员在自测的时候再也不须要应用 postman了,也不须要给前端独自写接口文档了,一下子就减少的本人的摸鱼工夫,美滋滋。

knife4j加强性能

什么是 knife4j 的加强性能?咱们在后面看到的只是 knife4j 最根底的应用形式,knife4j 还有很多弱小的性能还没有展现进去,比方:i18n国际化、接口增加作责、自定义文档、拜访权限管制、接口排序、到处离线文档、过滤申请参数等等,这些都是 knife4j 的加强性能,那如何开启 knife4j 的加强性能呢?

Knife4j自2.0.6版本开始,将目前在Ui界面中一些个性化配置剥离,开发者能够在后端进行配置,并且提供的knife4j-spring-boot-strater组件主动装载,开发者能够在配置文件中决定须要开启的性能。

springboot 中 knife4j的残缺参数如下:

knife4j:  enable: true  documents:    -      group: 2.X版本      name: 接口签名      locations: classpath:sign/*  setting:    language: zh-CN    enableSwaggerModels: true    enableDocumentManage: true    swaggerModelName: 实体类列表    enableVersion: false    enableReloadCacheParameter: false    enableAfterScript: true    enableFilterMultipartApiMethodType: POST    enableFilterMultipartApis: false    enableRequestCache: true    enableHost: false    enableHostText: 192.168.0.193:8000    enableHomeCustom: true    homeCustomLocation: classpath:markdown/home.md    enableSearch: false    enableFooter: false    enableFooterCustom: true    footerCustomContent: Apache License 2.0 | Copyright  2019-[浙江八一菜刀股份有限公司](https://gitee.com/xiaoym/knife4j)    enableDynamicParameter: false    enableDebug: true    enableOpenApi: false    enableGroup: true  cors: false  production: false  basic:    enable: false    username: test    password: 12313

knife4j 的加强性能是须要开启的,默认敞开,开启也是非常的简略,在以前的版本中,开发者须要在配置文件中手动应用@EnableKnife4j来应用加强,自2.0.6版本后,只须要在配置文件中配置knife4j.enable=true即可不在应用注解
留神:要应用Knife4j提供的加强,knife4j.enable=true必须开启。包含前面所解说到的所有加强性能,都须要设置这个参数。

上面我来介绍以下下面的这些属性值所表白的是什么意思

属性默认值阐明
knife4j.enablefalse是否开启Knife4j加强模式
knife4j.corsfalse是否开启一个默认的跨域配置,该性能配合自定义Host应用
knife4j.productionfalse是否开启生产环境保护策略,详情参考文档
knife4j.basic对Knife4j提供的资源提供BasicHttp校验,爱护文档
knife4j.basic.enablefalse敞开BasicHttp性能
knife4j.basic.usernamebasic用户名
knife4j.basic.passwordbasic明码
knife4j.documents自定义文档汇合,该属性是数组
knife4j.documents.group所属分组
knife4j.documents.name相似于接口中的tag,对于自定义文档的分组
knife4j.documents.locationsmarkdown文件门路,能够是一个文件夹(classpath:markdowns/*),也能够是单个文件(classpath:md/sign.md)
knife4j.setting前端Ui的个性化配置属性
knife4j.setting.enableAfterScripttrue调试Tab是否显示AfterScript性能,默认开启
knife4j.setting.languagezh-CNUi默认显示语言,目前次要有两种:中文(zh-CN)、英文(en-US)
knife4j.setting.enableSwaggerModelstrue是否显示界面中SwaggerModel性能
knife4j.setting.swaggerModelNameSwagger Models重命名SwaggerModel名称,默认
knife4j.setting.enableDocumentManagetrue是否显示界面中"文档治理"性能
knife4j.setting.enableReloadCacheParameterfalse是否在每个Debug调试栏后显示刷新变量按钮,默认不显示
knife4j.setting.enableVersionfalse是否开启界面中对某接口的版本控制,如果开启,后端变动后Ui界面会存在小蓝点
knife4j.setting.enableRequestCachetrue是否开启申请参数缓存
knife4j.setting.enableFilterMultipartApisfalse针对RequestMapping的接口申请类型,在不指定参数类型的状况下,如果不过滤,默认会显示7个类型的接口地址参数,如果开启此配置,默认展现一个Post类型的接口地址
knife4j.setting.enableFilterMultipartApiMethodTypePOST具体接口的过滤类型
knife4j.setting.enableHostfalse是否启用Host
knife4j.setting.enableHomeCustomfalse是否开启自定义主页内容
knife4j.setting.homeCustomLocation主页内容Markdown文件门路
knife4j.setting.enableSearchfalse是否禁用Ui界面中的搜寻框
knife4j.setting.enableFootertrue是否显示Footer
knife4j.setting.enableFooterCustomfalse是否开启自定义Footer
knife4j.setting.footerCustomContentfalse自定义Footer内容
knife4j.setting.enableDynamicParameterfalse是否开启动静参数调试性能
knife4j.setting.enableDebugtrue启用调试
knife4j.setting.enableOpenApitrue显示OpenAPI标准
knife4j.setting.enableGrouptrue显示服务分组

以下加强性能都须要

接口增加作者

前端李雷在对接接口的时候发现接口有问题,然而不晓得是谁在负责这个接口,通过层层查找,终于找到了是韩梅梅负责,这样大大的妨碍了开发的效率,所以这个时候在接口上标记对应的开发着,能让找人和背锅都能做到十分精准。

应用形式:增加注解 @ApiOperationSupport(author = "顺流星007")

@GetMapping(value = "/hello")    @ApiImplicitParam(name = "name",value = "姓名",required = true)    @ApiOperation("测试接口")    @ApiOperationSupport(author = "顺流星007")    public String test(@RequestParam("name") String name){        return "hello "+name+", I am  meimei han";    }


然而对于后端来说,在每个接口上都加上这个注解,着实有点浪费时间了,所以 knife4j 在收到反馈之后,决定在 Controller 类上减少一个注解,示意以后接口类下的所有接口都是该作者负责开发。
因而在 2.0.3 版本中新减少了 @ApiSupport 注解,该注解目前有两个属性,别离是author(作者)和order(排序)
留神:如果在controller 类上增加了@ApiSuppor 注解,并且在某个接口上也增加了 @ApiOperationSupport 注解,那么接口上的作者将会笼罩 controller 类上的作者

@RestController@RequestMapping(value = "/test")@ApiSupport(author = "顺流星007-controller")@Api(tags = "测试swagger")public class Knife4jTestController

@RestController@RequestMapping(value = "/test")@ApiSupport(author = "顺流星007-controller")@Api(tags = "测试swagger")public class Knife4jTestController {    @GetMapping(value = "/hello")    @ApiImplicitParam(name = "name",value = "姓名",required = true)    @ApiOperation("测试接口")    @ApiOperationSupport(author = "顺流星顺流星007-test")    public String test(@RequestParam("name") String name){        return "hello "+name+", I am  meimei han";    }}

拜访权限管制

尽管 knife4j给咱们提供了很不便的在线接口文档,俗话说的好,凡事都具备两面性,无利天然也有弊,那就是在生茶环境上,也会显示出接口文档,这是十分危险的一件事件,问题如下:

  • 零碎部署生产环境时,咱们想屏蔽Swagger的文档性能,不论是接口或者html文档
  • 通常咱们有时候须要生产环境部署后,又须要Swagger的文档调试性能,辅助开发者调试,然而存在安全隐患,没有对Swagger的资源接口过滤

Knife4j 基于 Servlet 体系提供了过滤 Filter 性能,如果开发者应用 Spring Boot 开发框架进行开发的话,只需在application.properties或者application.yml配置文件中配置相干属性即可不便的解决下面的问题,不必删除 Springfox-swagger 的 jar 包或者删除相干代码等简单的操作,晋升开发体验。

资源屏蔽

目前Springfox-Swagger以及Knife4j提供的资源接口包含如下

资源阐明
/doc.htmlKnife4j提供的文档拜访地址
/v2/api-docs-extKnife4j提供的加强接口地址,自2.0.6版本后删除
/swagger-resourcesSpringfox-Swagger提供的分组接口
/v2/api-docsSpringfox-Swagger提供的分组实例详情接口
/swagger-ui.htmlSpringfox-Swagger提供的文档拜访地址
/swagger-resources/configuration/uiSpringfox-Swagger提供
/swagger-resources/configuration/securitySpringfox-Swagger提供

我的项目公布到生产环境之后,咱们须要屏蔽 swagger 相干的资源,因为 Knife4j 基于 Servlet 体系提供了过滤 Filter 性能,所以就不须要咱们再去造轮子了,间接应用即可。

springboot 只须要在配置文件中做如下批改即可

knife4j:  # 开启加强配置   enable: true # 开启生产环境屏蔽  production: true

而后重启我的项目

如果看到如下信息,阐明资源曾经屏蔽胜利,然而你又不想在生产环境中屏蔽 swagger 资源,只想给一部分人应用,也是能够的,退出权限校验即可。

拜访页面加权管制

针对Swagger的资源接口,Knife4j提供了简略的Basic认证性能

简略点说,指定一个用户名和明码,拜访 Swagger 文档须要验证登录名和明码,验证通过之后能力失常拜访。

knife4 容许开发者在配置文件(application.yml/properties)中减少一组用户名和明码。

knife4j:  # 开启加强配置   enable: true # 开启Swagger的Basic认证性能,默认是false  basic:      enable: true      # Basic认证用户名      username: test      # Basic认证明码      password: 123

如果用户开启了 basic (knife4j.basic.enable = true)认证性能,然而没有指定 username 和password,那么 knife4j 提供了一组默认的用户名明码

admin/123321

配置好application.yml 文件之后,咱们再次重启我的项目(这个时候须要将之前设置的资源屏蔽须要去掉哦)

接口排序

咱们在开发中,一个 controller 中往往会存在很多的接口,这样咱们在文档查找的时候就会变得很苦恼,所以 knife4j 在 @ApiOperationSupport注解中减少了 order 字段,用于接口排序。

在应用此注解之前须要开启加强性能。

package com.ymy.notes.controller;import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;import com.github.xiaoymin.knife4j.annotations.ApiSupport;import io.swagger.annotations.Api;import io.swagger.annotations.ApiImplicitParam;import io.swagger.annotations.ApiOperation;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestParam;import org.springframework.web.bind.annotation.RestController;@RestController@RequestMapping(value = "/test")@ApiSupport(author = "顺流星007-controller")@Api(tags = "测试swagger")public class Knife4jTestController {    @GetMapping(value = "/hello1")    @ApiImplicitParam(name = "name",value = "姓名",required = true)    @ApiOperation("测试接口01")    @ApiOperationSupport(author = "顺流星顺流星007-test",order = 1)    public String test01(@RequestParam("name") String name){        return "hello "+name+", I am  meimei han";    }    @GetMapping(value = "/hello3")    @ApiImplicitParam(name = "name",value = "姓名",required = true)    @ApiOperation("测试接口03")    @ApiOperationSupport(author = "顺流星顺流星007-test",order = 3)    public String test03(@RequestParam("name") String name){        return "hello "+name+", I am  meimei han";    }    @GetMapping(value = "/hello2")    @ApiImplicitParam(name = "name",value = "姓名",required = true)    @ApiOperation("测试接口02")    @ApiOperationSupport(author = "顺流星顺流星007-test",order = 2)    public String test02(@RequestParam("name") String name){        return "hello "+name+", I am  meimei han";    }}

分组排序

分组,顾名思义,就是多个 controller 之间的排序,开发者能够通过注解实现每个controller 之间的排序,实现这个性能的注解一共有三个,具体如下:

  • @ApiSupport
  • @ApiSort
  • @Api

这三个注解是存在优先级的,也就是说,当同时应用时,只会有一个注解失效,所以在应用的时候须要特地留神。优先级规定如下:

@ApiSupport > @ApiSort > @Api

controller 之间的排序规定为降序,越大的排在越靠前,然而排序的最小值肯定须要大于 0 。

@ApiSupport

@RestController@RequestMapping(value = "/test")@ApiSupport(author = "顺流星007-controller",order = 999)@Api(tags = "测试swagger")public class Knife4jTestController 

@ApiSort

@RestController@RequestMapping(value = "/test")@ApiSort(value = 999)@Api(tags = "测试swagger")public class Knife4jTestController 

@Api

@RestController@RequestMapping(value = "/test")@Api(tags = "测试swagger",position = 999)public class Knife4jTestController

尽管 @Api 中的position 字段也能实现 controller 之间的排序,然而该字段曾经被 knife4j 标记为不举荐应用,所以还是举荐应用第一种排序形式(@ApiSupport)。

申请参数缓存

咱们在调试接口的时候,有的接口会有很多参数,当咱们好不容易填好了所有的参数,因为咱们不小心敞开了页面,下次再调试的时候发现还须要再次将参数输出一遍,心态会爆炸吧,所以 knife4j 在文档治理中减少了一个选项:开启申请参数缓存

勾选这个选项之后,你填写的参数将会被 knife4j 缓存,敞开页面也不会失落,是不是很兽性呢?

编写代码,筹备数据

 @PostMapping(value = "/saveUser")    @ApiOperation("保留用户信息")    @ApiOperationSupport(author = "顺流星顺流星007")    public String saveUser(@RequestBody UserDTO userDTO){        System.out.println("前端传递的用户信息:"+ userDTO);        return "save success";    }
package com.ymy.notes.dto;import io.swagger.annotations.ApiModel;import io.swagger.annotations.ApiModelProperty;import lombok.Getter;import lombok.Setter;import lombok.ToString;@ApiModel("用户信息")@Getter@Setter@ToStringpublic class UserDTO {    @ApiModelProperty(value = "用户名")    private String username;    @ApiModelProperty(value = "性别")    private String gender;    @ApiModelProperty(value = "手机号码")    private String phone;}

不过你不能快乐的太早,缓存也不是肯定会失效的,我已知的这两种状况,缓存将会生效,在应用的时候须要留神哦。

  • 在字段的 @ApiModelProperty 注解中增加 example (属性的示例值)属性,那么, knife4j 将不会应用缓存,应用的是后端指定的 example 。
public class UserDTO {    @ApiModelProperty(value = "用户名",example = "李雷")    private String username;    @ApiModelProperty(value = "性别",example = "男")    private String gender;    @ApiModelProperty(value = "手机号码",example = "18888888888")    private String phone;}
  • 当域名产生扭转时,所有缓存将会生效。

动静申请参数

作为开发,不晓得大家有没有做过这种操作,接口参数并不是实体对象接管,而是Map,尽管我没这么做过,然而我见过他人这么写过,当后端程序员应用 Map 接管参数的时候,Swagger ui 会怎么展现呢?咱们一起来模仿一下。

定义一个以 Map 接管参数的接口

@PostMapping(value = "/saveUserForMap")    @ApiOperation("新增用户信息-map")    @ApiOperationSupport(author = "顺流星007")    private String saveUserForMap(Map<String,Object> userDTO ){        System.out.println("前端传递的用户信息:"+ userDTO);        return "save success";    }

咱们来看看 Swagger ui 如何展现这个 Map类型的参数

这。。。。。要是前端看到这样的接口文档,心里开始问候后端的家人了吧,如何解决这个问题呢?其实很简略,knife4j 早已为咱们想到了解决方案,招到文档治理 - 个性化设置 ,勾选开启动静申请参数就能解决这个问题了。

咱们当初再来看看勾选了 开启动静申请参数之后的成果

在输出了一个参数之后,参数列表会主动追加新的一行,然而参数的 key 却须要前端人员本人填写,前端有很大可能是不晓得参数的key,所以还是须要找后端开发人员,尽管开启了动静参数能够减少参数的个数,然而还没没有方法解决参数值的问题,那这个怎么解决呢?那这就是另外一个加强性能了:动静申请参数增加文档正文

过滤申请参数

咱们在开发过程中,常常会遇到这样的一个问题,新增和批改接口,批改接口须要传递批改的记录id,然而新增则不须要,而后端往往会将批改和新增的入参对象设置为一个对象,那么这个对象中必然会存在 id 字段,这就会对新增造成误导,前端可能百思不得其解,新增的 id 我应该怎么传呢? 总不可能去偷一个吧。

所以,knife4j 反对了申请参数的过滤(疏忽),实现形式也是十分的简略,应用自定义加强注解ApiOperationSupport中的ignoreParameters属性,能够强制疏忽要显示的参数

应用字段疏忽之前咱们得先理解一下字段疏忽的规定:

  • 1.例如新增接口时,某实体类不须要显示Id,即可应用该属性对参数进行疏忽.ignoreParameters={"id"}
  • 2.如果存在多个档次的参数过滤,则应用名称.属性的形式,例如 ignoreParameters={"uptModel.id","uptModel.uptPo.id"},其中uptModel是实体对象参数名称,id为其属性,uptPo为实体类,作为uptModel类的属性名称
  • 3。如果参数层级只是一级的状况下,并且参数是实体类的状况下,不须要设置参数名称,间接给定属性值名称即可
  • 4.如果实体类属性中是通过List这种数组的形式,那么过滤规定会有所不同,在属性前面须要追加一个下标[0]ignoreParameters={"uptModel.uptPo[0].id"}

实现此性能须要开启加强性能。

表单提交和 JSON 提交的格局是不一样的,所以这里须要离开解说一下,咱们先来看表单提交怎么疏忽字段属性。

前置条件:咱们先创立两个 DTO 用来接管前端传递二点参数

package com.ymy.notes.dto;import io.swagger.annotations.ApiModel;import io.swagger.annotations.ApiModelProperty;import lombok.Getter;import lombok.Setter;import lombok.ToString;@ApiModel("用户信息")@Getter@Setter@ToStringpublic class UserDTO {    @ApiModelProperty(value = "用户id")    private Long id;    @ApiModelProperty(value = "用户名",example = "李雷")    private String username;    @ApiModelProperty(value = "性别",example = "男")    private String gender;    @ApiModelProperty(value = "手机号码",example = "18888888888")    private String phone;    @ApiModelProperty(value = "用户收货地址信息")    private UserAddressDTO userAddressDTO;}
package com.ymy.notes.dto;import io.swagger.annotations.ApiModelProperty;import lombok.Getter;import lombok.Setter;import lombok.ToString;@Getter@Setter@ToStringpublic class UserAddressDTO {    @ApiModelProperty(value = "播种地址的记录id")    private Long id;        @ApiModelProperty(value = "省")    private String province;    @ApiModelProperty(value = "市")    private String city;    @ApiModelProperty(value = "区")    private String district;    @ApiModelProperty(value = "具体地址")    private String addr;}

表单提交

创立新增接口和批改接口,并且心愿在增加的时候过滤掉 UserDTO 中的 id 字段 与 UserAddressDTO 中的 id 字段,因为新增用户和播种地址的时候是没有 id 信息的,只有新增实现之后才会存在 id字段。

  @ApiOperationSupport(author = "顺流星007",ignoreParameters = {"id","userAddressDTO.id"})
    @PostMapping(value = "/saveUser")    @ApiOperation("新增用户信息-表单")    @ApiOperationSupport(author = "顺流星007",ignoreParameters = {"id","userAddressDTO.id"})    public String saveUser( UserDTO userDTO){        System.out.println("前端传递的用户信息:"+ userDTO);        return "save success";    }    @PostMapping(value = "/updateUser")    @ApiOperation("编辑用户信息")    @ApiOperationSupport(author = "顺流星007")    public String updateUser( UserDTO userDTO){        System.out.println("前端传递的用户信息:"+ userDTO);        return "edit success";    }

在过滤字段的时候,第一层咱们只有填写对象中的属性名即可,但如果须要过滤第二层,依据疏忽规定中的第二条,咱们在 UserDTO 对象中引入 UserAddressDTO 对象:private UserAddressDTO userAddressDTO; 咱们还须要疏忽 UserAddressDTO 对象中的 id 属性,那么须要填上 userAddressDTO.id ,其中 userAddressDTO 要与 UserDTO 对象中的 UserAddressDTO 属性名统一。

代码写好了,咱们一起来看看成果。

增加接口

这里咱们看不到 UserDTO 中的 id ,同时也看不到 UserAddressDTO 中的 id,疏忽胜利。

批改接口

因为咱们在批改的时候并没有疏忽 这两个字段,所以能够失常显示,这也是没有问题的。

JSON提交

因为表单提交和 json 提交的格局存在肯定的差别,所以他们疏忽参数的格局也存在肯定的差别,咱们将原来的批改和批改接口的参数接管形式改为 json 格局并且放弃和表单提交一样的疏忽格局(为了看到更显著的成果,我在多疏忽一个字段:"username")。

@ApiOperationSupport(author = "顺流星007",ignoreParameters = {"id","userAddressDTO.id"})
 @PostMapping(value = "/saveUser")    @ApiOperation("新增用户信息")    @ApiOperationSupport(author = "顺流星007",ignoreParameters = {"id","userAddressDTO.id"})    public String saveUser(@RequestBody UserDTO userDTO){        System.out.println("前端传递的用户信息:"+ userDTO);        return "save success";    }    @PostMapping(value = "/updateUser")    @ApiOperation("编辑用户信息")    @ApiOperationSupport(author = "顺流星007")    public String updateUser(@RequestBody UserDTO userDTO){        System.out.println("前端传递的用户信息:"+ userDTO);        return "save success";    }

咱们先来看看成果会是什么样子?是否可能胜利疏忽呢?

新增接口

哦吼,竟然也疏忽胜利了,卧槽,这打脸的也太快了,UserDTO 中被疏忽一个字段:id,,UserAddressDTO 对象我疏忽了 id 字段,咱们查看 ui 界面发现的确疏忽胜利了,这是怎么回事呢?具体为啥,我也不太分明,可能是 3.x 做了降级,疏忽形式和表单统一了,兴许是3.x 不太稳固,呈现了诡异的bug,导致了 json 格局也能这样疏忽,尽管这样同样能够疏忽胜利,因为我不确定是高版本做了优化没有更新文档还是诡异bug导致,我还是持续介绍一下 json 格局参数的疏忽格局,有可能同学们这样应用却是不能够的,我举荐还是依照上面的格局编写。

json 格局如何疏忽呢?

业余说法是:实例名.属性名,以新增用户为例,咱们须要过滤用户id,那么写法就是:userDTO.id其中 userDTO 为 saveUser() 的 参数名

当初咱们来革新一下咱们的代码

@PostMapping(value = "/saveUser")    @ApiOperation("新增用户信息")    @ApiOperationSupport(author = "顺流星顺流星007",ignoreParameters = {"userDTO.id","userDTO.userAddressDTO.id"})    public String saveUser(@RequestBody UserDTO userDTO){        System.out.println("前端传递的用户信息:"+ userDTO);        return "save success";    }

咱们一起来看看成果

这里还有一个状况是须要留神的,如果你疏忽的字段在对象的第二层,那么在申请示例中,将会看不到实现的示例代码,会缺斤少两,可能 3.x 的bug吧,所以结尾我申明过, 3.x 目前可能还不够稳固,降级或者应用的同学还是须要谨慎啊。

搜寻API接口

在文档的右上角,Knife4j提供了文档检索的性能

那这个搜寻框都反对哪些关键字搜寻呢?

  • 接口地址。
  • 接口名称。
  • 接口形容。

以上三个搜寻都是含糊搜寻,然而,须要留神的是:目前检索性能仅对以后分组下的曾经加载的接口无效,对于分组中的接口,没有加载的状况下是搜寻不到的,这点须要留神,换句话说该检索性能并非是全局检索,只对以后你看到的整体所有接口列表进行检索

版本要求:knife4j 版本>2.0.1 应用此规定。

全局参数

Knife4j提供基于UI长期设置全局参数性能,例如后盾全局token参数等.提供该性能次要是不便开发者进行调试

目前全局参数性能次要提供两种参数类型:query(表单)、header(申请头)

如果后端Swagger有配置全局参数,该性能能够忽视

性能目录:文档治理 -> 全局参数设置

自定义主页内容

不晓得大家有没有感觉 swagger 的首页有一种很丑的感觉?是不是很不想看到它呢?那么接下来这条加强性能,决定是你的福利啊,knife4j 反对开发者本人替换首页,不过目前只反对 md 格局。

须要开启加强性能

Knife4j自2.0.8版本开始,开发者能够提供一个Markdown文件来自定义显示Home主页的显示内容,通过配置yml来进行开启,配置文件如下

knife4j:  enable: true  setting:    enableHomeCustom: true    homeCustomLocation: classpath:markdown/home.md

属性阐明:

  • enableHomeCustom:该属性为Boolean值,默认false,如果开发者要自定义主页内容,该选项设置为true
  • homeCustomLocation:提供一个主页的Markdown文件地位

咱们先在 resources 目录下创立一个 markdown 目录,而后在 markdown 目录下创立 home.md

<center><h1>顺流星007</h1></center>昵称:顺流星007职业:java开发工程开源博客地址:http://yaomaoyang.com   https://blog.csdn.net/qq_33220089分割邮箱:361426201@qq.com

下面是home.md 的内容,接下来咱们重启我的项目,一起来看看成果

咦,为什么没有产生扭转呢?明明曾经批改了啊,别急,咱们遗记了最外围的一步,所以它没有替换胜利,开发者须要在创立Docket逻辑分组对象时,通过Knife4j提供的工具对象OpenApiExtensionResolver将扩大属性进行赋值。

package com.ymy.notes.config.kinfe4j;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.Contact;import springfox.documentation.spi.DocumentationType;import springfox.documentation.spring.web.plugins.Docket;import springfox.documentation.swagger2.annotations.EnableSwagger2;@Configuration@EnableSwagger2public class Knife4jConfiguration {    private final OpenApiExtensionResolver openApiExtensionResolver;    @Autowired    public Knife4jConfiguration(OpenApiExtensionResolver openApiExtensionResolver) {        this.openApiExtensionResolver = openApiExtensionResolver;    }    @Bean(value = "defaultApi2")    public Docket defaultApi2() {        String groupName="3.X版本";        Docket docket=new Docket(DocumentationType.OAS_30)                .apiInfo(new ApiInfoBuilder()                        .title("这是knife4j API ")                        .description("# 这里记录服务端所有的接口的入参,出参等等信息")                        .termsOfServiceUrl("http://yaomaoyang.com")                        .contact(new Contact("顺流星","http://yaomaoyang.com","361426201@qq.com"))                        .version("3.0")                        .build())                //分组名称                .groupName(groupName)                .select()                //这里指定Controller扫描包门路                .apis(RequestHandlerSelectors.basePackage("com.ymy.notes.controller"))                .paths(PathSelectors.any())                .build()                .extensions(openApiExtensionResolver.buildSettingExtensions());        return docket;    }}

通过下面示例代码,次要步骤如下:

1、通过@Autowired注解引入Knife4j向Spring容器注入的Bean对象OpenApiExtensionResolver

2、最终在Dcoket对象构建后,通过调用Docket对象的extensions办法进行插件赋值

3、插件赋值须要调用OpenApiExtensionResolver提供的buildSettingExtensions办法,获取x-settings的加强属性

这样,咱们就能看到成果了。

禁用调试

在以前的版本中,开发者如果要禁用调试性能,是通过在服务端创立UiConfiguration的实体Bean对象,配置supportMethod来达到禁用局部接口的调试,自2.0.8版本后,该属性被废除

此性能须要开启加强模式能力应用

如果开发者须要禁用调试性能,只须要在配置文件中进行操作即可

knife4j:  enable: true  setting:    enableDebug: false

属性阐明:

  • enableDebug:该属性是一个Boolean值,代表是否启用调试性能,默认值为true(代表开启调试),如果要禁用调试,该值设为false

同样,此操作也须要开发者在创立Docket逻辑分组对象时,通过Knife4j提供的工具对象OpenApiExtensionResolver将扩大属性进行赋值。

package com.ymy.notes.config.kinfe4j;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.Contact;import springfox.documentation.spi.DocumentationType;import springfox.documentation.spring.web.plugins.Docket;import springfox.documentation.swagger2.annotations.EnableSwagger2;@Configuration@EnableSwagger2public class Knife4jConfiguration {    private final OpenApiExtensionResolver openApiExtensionResolver;    @Autowired    public Knife4jConfiguration(OpenApiExtensionResolver openApiExtensionResolver) {        this.openApiExtensionResolver = openApiExtensionResolver;    }    @Bean(value = "defaultApi2")    public Docket defaultApi2() {        String groupName="3.X版本";        Docket docket=new Docket(DocumentationType.OAS_30)                .apiInfo(new ApiInfoBuilder()                        .title("这是knife4j API ")                        .description("# 这里记录服务端所有的接口的入参,出参等等信息")                        .termsOfServiceUrl("http://yaomaoyang.com")                        .contact(new Contact("顺流星","http://yaomaoyang.com","361426201@qq.com"))                        .version("3.0")                        .build())                //分组名称                .groupName(groupName)                .select()                //这里指定Controller扫描包门路                .apis(RequestHandlerSelectors.basePackage("com.ymy.notes.controller"))                .paths(PathSelectors.any())                .build()                .extensions(openApiExtensionResolver.buildSettingExtensions());        return docket;    }}

全副操作实现之后,重启我的项目看成果

调试和 open 按钮没有了。

禁用搜寻框

发者如果想要禁用Ui界面中的搜寻性能,须要通过加强属性进行配置,此性能须要开启加强性能。

knife4j:  enable: true  setting:    enableSearch: false

属性阐明:

  • enableSearch:该属性是一个Boolean值,代表是否启用搜寻性能,默认值为true(代表开启搜寻),如果要禁用搜寻,该值设为false

同样,此操作也须要开发者在创立Docket逻辑分组对象时,通过Knife4j提供的工具对象OpenApiExtensionResolver将扩大属性进行赋值。具体的代码实现请参考禁用调试自定义主页内容,我这里就不反复了。

重启我的项目看成果

好了,knife4j 的介绍到这里就完结了,还有一些高级的性能,就须要大家本人缓缓的摸索了,本文大部分参考了 knife4j 的官网文档,本人写的 demo,如果感觉对您有帮忙,心愿留下您贵重的一赞。