文章目录
SpringBoot 整合knife4j
Knife4j是一款基于Swagger 2的在线API文档框架
在Spring Boot中,使用此框架时,需要:
- 添加依赖
- 在配置文件(`application.properties`)中开启增强模式
- 编写配置类(代码相对固定,建议CV)
引入knife4j
添加依赖
<dependency><groupId>com.github.xiaoymin</groupId><artifactId>knife4j-spring-boot-starter</artifactId><version>3.0.3</version></dependency>
创建 Swagger 配置依赖
packagecom.yolo.knife4j.config;importio.swagger.annotations.Api;importlombok.extern.slf4j.Slf4j;importorg.springframework.beans.factory.annotation.Value;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;importorg.springframework.context.annotation.Import;importspringfox.bean.validators.configuration.BeanValidatorPluginsConfiguration;importspringfox.documentation.builders.*;importspringfox.documentation.service.*;importspringfox.documentation.spi.DocumentationType;importspringfox.documentation.spring.web.plugins.Docket;importspringfox.documentation.swagger2.annotations.EnableSwagger2WebMvc;@Slf4j@Configuration@EnableSwagger2WebMvc// 对JSR303提供支持@Import(BeanValidatorPluginsConfiguration.class)publicclassKnife4jConfig{@Value("${spring.application.name}")privateString applicationName;@BeanpublicDocketdefaultApi(){returnnewDocket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()).groupName(applicationName).select()// 添加@Api注解才显示.apis(RequestHandlerSelectors.withClassAnnotation(Api.class))// 这里指定Controller扫描包路径// .apis(RequestHandlerSelectors.basePackage("com.yolo")).paths(PathSelectors.any()).build();}/**
* swagger-api接口描述信息
*/privateApiInfoapiInfo(){returnnewApiInfoBuilder().title("API文档").description("API文档").contact(newContact("yolo","https://gitee.com/huanglei1111","[email protected]")).version("1.0.0").build();}}
application.yml配置文件
# https://doc.xiaominfo.com/knife4jknife4j:# 开启增强配置enable:true# 是否开启生产环境屏蔽 true:关闭swagger,false:开启swaggerproduction:falsebasic:# 是否开启认证enable:false# Basic认证用户名username: admin
# Basic认证密码password:123456spring:application:name: test-knife4j
注解
@Api(tags ={“用户操作”})
加在controller类上
tags表示该类的标签,在页面会独立显示一个菜单
@ApiOperation(value = “保存用户”, notes = “保存时,ID由数据库生成,无需填写,有则忽略”, tags = “保存”)
加在相应的请求处理方法上
value表示该方法的说明
notes相当于对该方法的详细说明,也就是更加完整的描述
tags 表示标签,,在页面会独立显示一个菜单
@ApiImplicitParam(name = “id”, value = “用户ID”, defaultValue = “1”)
方法只有一个基本类型参数时加在方法上。方法有多个参数时加在@ApiImplicitParams内
name 参数中属性的名字
value 对这个属性的描述
defaultValue 默认值,这个还是有必要填写的,在页面进行请求时,会自动填充
@ApiImplicitParams(value ={})
用在请求方法上
这个注解必须和@ApiImplicitParam配合使用
当请求方法中的请求参数很多的时候,例如saveUser(String username,Integer age,Date birthday,String phone)@ApiParam(value = “当前页”, defaultValue = “1”)
加在请求方法的普通参数上
value的值是对该参数的说明
与@ApiImplicitParam使用的效果等同,根据个人喜好进行使用
@ApiModel(value = “用户信息”)
加在请求方法的对象类上
value 对该对象参数的描述
例如有一个请求方法save(UserDTO userDTO), 则需要加在UserDTO这个类上面(可以参照下面的示例)@ApiModelProperty(value = “用户ID”, example = “1”)
加在请求方法的参数对象的属性上
value 对该属性的描述
example 属性的示例值,在页面会自动填充该值
@ApiIgnore:注解类、参数、方法,注解后将不在Swagger UI中显示
案例
packagecom.yolo.knife4j.controller;importcn.hutool.core.collection.ListUtil;importcom.yolo.knife4j.base.ResultVo;importcom.yolo.knife4j.dto.UserAddRequest;importcom.yolo.knife4j.vo.StudentVO;importcom.yolo.knife4j.vo.UserVO;importio.swagger.annotations.*;importorg.springframework.web.bind.annotation.*;importjavax.validation.Valid;importjava.util.Date;@ApiResponses(value ={@ApiResponse(code =200, message ="接口返回成功状态"),@ApiResponse(code =500, message ="接口返回未知错误,请联系开发人员调试")})@Api(tags ="用户")@RestController@RequestMapping("/user")publicclassUserController{@ApiOperation(value ="保存用户", notes ="简单传参")@PostMapping("/add")publicResultVo<Object>add(@RequestBody@ValidUserAddRequest userAddRequest){returnResultVo.builder().build().setCode(200).setSuccess(true).setTime(newDate()).setMsg("保存用户成功").setData(userAddRequest);}@ApiOperation(value ="保存用户2", notes ="复杂传参")@PostMapping("/add2")publicResultVo<Object>add2(@RequestBody@ValidUserAddRequest userAddRequest){returnResultVo.builder().build().setCode(200).setSuccess(true).setTime(newDate()).setMsg("保存用户成功").setData(userAddRequest);}@GetMapping("/list")@ApiOperation(value ="查找用户列表", notes ="根据id查找单个用户")publicResultVo<Object>list(@RequestParam@ApiParam(value ="当前页", defaultValue ="1")Integer pageNum,@RequestParam@ApiParam(value ="页大小", defaultValue ="10")Integer pageSize){UserVO vo =newUserVO();StudentVO studentVO =StudentVO.builder().build().setAddress("wuhan").setCode(2);
vo.setStudentVOS(ListUtil.of(studentVO));returnResultVo.builder().build().setCode(200).setSuccess(true).setTime(newDate()).setMsg("查找用户列表").setData(vo);}@DeleteMapping("/{id}")@ApiOperation(value ="删除用户", notes ="删除后无法恢复")@ApiImplicitParam(name ="id", value ="用户ID", defaultValue ="1")publicResultVo<Object>delete(@PathVariable(name ="id")Long id){returnResultVo.builder().build().setCode(200).setSuccess(true).setTime(newDate()).setMsg("删除用户");}}
响应参数
packagecom.yolo.knife4j.base;importcom.fasterxml.jackson.annotation.JsonFormat;importio.swagger.annotations.ApiModel;importio.swagger.annotations.ApiModelProperty;importlombok.AllArgsConstructor;importlombok.Builder;importlombok.Data;importlombok.NoArgsConstructor;importlombok.experimental.Accessors;importjava.io.Serializable;importjava.util.Date;@Data@Builder@Accessors(chain =true)@ApiModel("响应参数")@AllArgsConstructor@NoArgsConstructorpublicclassResultVo<T>implementsSerializable{privatestaticfinallong serialVersionUID =-8054007511410819665L;@ApiModelProperty(value ="响应状态码", example ="1", dataType ="Integer")privateint code;// 是否成功标识.true表示成功,false表示失败@ApiModelProperty("success标识,true表示成功,false表示失败")privateboolean success;// 操作成功时需要响应给客户端的响应数据@ApiModelProperty("响应信息")privateString msg;@ApiModelProperty("响应数据")privateT data;@ApiModelProperty("当前时间")@JsonFormat(pattern ="yyyy-MM-dd HH:mm:ss", timezone ="GMT+8")privateDate time;}
tips: http://127.0.0.1:8080/doc.html
这里端口,就是你运行项目的端口
knife4j增强功能
springboot 中 knife4j的完整参数如下:
knife4j:enable:truedocuments:-group: 2.X版本
name: 接口签名
locations: classpath:sign/*
setting:language: zh-CN
enableSwaggerModels:trueenableDocumentManage:trueswaggerModelName: 实体类列表
enableVersion:falseenableReloadCacheParameter:falseenableAfterScript:trueenableFilterMultipartApiMethodType: POST
enableFilterMultipartApis:falseenableRequestCache:trueenableHost:falseenableHostText: 192.168.0.193:8000enableHomeCustom:truehomeCustomLocation: classpath:markdown/home.md
enableSearch:falseenableFooter:falseenableFooterCustom:truefooterCustomContent: Apache License 2.0 | Copyright 2019-[浙江八一菜刀股份有限公司](https://gitee.com/xiaoym/knife4j)
enableDynamicParameter:falseenableDebug:trueenableOpenApi:falseenableGroup:truecors:falseproduction:falsebasic:enable:falseusername: test
password:12313
接口添加作者
添加作者有俩种方式
- 在方法上使用注解
@ApiOperationSupport(author = "yolo-test")
- 在controller类上使用注解
@ApiSupport(author = "yolo-controller")
如果在方法上使用了注解,并且也在类上使用了注解,那么最后的展示结果以方法上的注解为准
资源屏蔽
当我们在生成环境的时候不想显示接口文档,由于 Knife4j 基于 Servlet 体系提供了过滤 Filter 功能,所以就不需要我们再去造轮子了,直接使用即可
knife4j:# 开启增强配置enable:true# 是否开启生产环境屏蔽 true:关闭swagger,false:开启swaggerproduction:true
然后重启项目
访问页面加权控制
针对Swagger的资源接口,Knife4j提供了简单的Basic认证功能
简单点说,指定一个用户名和密码,访问 Swagger 文档需要验证登录名和密码,验证通过之后才能正常访问
如果用户开启了 basic (knife4j.basic.enable = true)认证功能,但是没有指定 username 和password,那么 knife4j 提供了一组默认的用户名密码
admin/123321
knife4j:# 开启增强配置enable:true# 是否开启生产环境屏蔽 true:关闭swagger,false:开启swaggerproduction:falsebasic:# 是否开启认证enable:true# Basic认证用户名username: admin
# Basic认证密码password:123456
如果开启生产环境屏蔽了,开启basic认证是不生效的
接口排序
@ApiOperationSupport注解中增加了 order 字段,用于接口排序。在使用此注解之前需要开启增强功能
分组排序
分组,顾名思义,就是多个 controller 之间的排序,开发者可以通过注解实现每个controller 之间的排序,实现这个功能的注解一共有三个,具体如下
@ApiSupport
@RestController@RequestMapping(value ="/test")@ApiSupport(author ="yolo-controller",order =999)@Api(tags ="测试swagger")publicclassKnife4jTestController
@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
Tips:
这三个注解是存在优先级的,也就是说,当同时使用时,只会有一个注解生效,所以在使用的时候需要特别注意。优先级规则如下
@ApiSupport > @ApiSort>@Api
请求参数缓存
我们在调试接口的时候,有的接口会有很多参数,当我们好不容易填好了所有的参数,由于我们不小心关闭了页面,下次再调试的时候发现还需要再次将参数输入一遍,心态会爆炸吧,所以 knife4j 在文档管理中增加了一个选项:开启请求参数缓存
Tips:
俩种情况会失效
1、 @ApiModelProperty 注解中添加 example (属性的示例值)属性,那么, knife4j 将不会使用缓存,使用的是后端指定的 example
2、当域名发生改变时,所有缓存将会失效
过滤请求参数
我们在开发过程中,经常会遇到这样的一个问题,新增和修改接口,修改接口需要传递修改的记录id,但是新增则不需要,而后端往往会将修改和新增的入参对象设置为一个对象,那么这个对象中必然会存在 id 字段,这就会对新增造成误导
所以,knife4j 支持了请求参数的过滤(忽略),实现方式也是非常的简单,使用自定义增强注解ApiOperationSupport中的ignoreParameters属性,可以强制忽略要显示的参数
这里表单和json格式过滤参数是不一样的
我们先看表单格式
@ApiModel("用户信息")@Getter@Setter@ToStringpublicclassUserDTO{@ApiModelProperty(value ="用户id")privateLong id;@ApiModelProperty(value ="用户名",example ="李雷")privateString username;@ApiModelProperty(value ="性别",example ="男")privateString gender;@ApiModelProperty(value ="手机号码",example ="18888888888")privateString phone;@ApiModelProperty(value ="用户收货地址信息")privateUserAddressDTO userAddressDTO;}@Getter@Setter@ToStringpublicclassUserAddressDTO{@ApiModelProperty(value ="收获地址的记录id")privateLong id;@ApiModelProperty(value ="省")privateString province;@ApiModelProperty(value ="市")privateString city;@ApiModelProperty(value ="区")privateString district;@ApiModelProperty(value ="详细地址")privateString addr;}@PostMapping(value ="/saveUser")@ApiOperation("新增用户信息-表单")@ApiOperationSupport(author ="yolo",ignoreParameters ={"id","userAddressDTO.id"})publicStringsaveUser(UserDTO userDTO){System.out.println("前端传递的用户信息:"+ userDTO);return"save success";}@PostMapping(value ="/updateUser")@ApiOperation("编辑用户信息")@ApiOperationSupport(author ="yolo")publicStringupdateUser(UserDTO userDTO){System.out.println("前端传递的用户信息:"+ userDTO);return"edit success";}
在过滤字段的时候,第一层我们只要填写对象中的属性名即可,但如果需要过滤第二层,根据忽略规则中的第二条,我们在 UserDTO 对象中引入 UserAddressDTO 对象:private UserAddressDTO userAddressDTO; 我们还需要忽略 UserAddressDTO 对象中的 id 属性,那么需要填上 userAddressDTO.id ,其中 userAddressDTO 要与 UserDTO 对象中的 UserAddressDTO 属性名一致
新增操作没有id
编辑操作
JSON格式忽略
专业说法是:实例名.属性名,以新增用户为例,我们需要过滤用户id,那么写法就是:userDTO.id,其中 userDTO 为 saveUser() 的 参数名
@PostMapping(value ="/saveUser")@ApiOperation("新增用户信息")@ApiOperationSupport(author ="yolo",ignoreParameters ={"userDTO.id","userDTO.userAddressDTO.id"})publicStringsaveUser(@RequestBodyUserDTO userDTO){System.out.println("前端传递的用户信息:"+ userDTO);return"save success";}
禁用调试
knife4j:enable:truesetting:enableDebug:false
enableDebug:该属性是一个Boolean值,代表是否启用调试功能,默认值为true(代表开启调试),如果要禁用调试,该值设为false
同样,此操作也需要开发者在创建Docket逻辑分组对象时,通过Knife4j提供的工具对象OpenApiExtensionResolver将扩展属性进行赋值
禁用搜索框
发者如果想要禁用Ui界面中的搜索功能,需要通过增强属性进行配置,此功能需要开启增强功能
knife4j:enable:truesetting:enableSearch:false
enableSearch:该属性是一个Boolean值,代表是否启用搜索功能,默认值为true(代表开启搜索),如果要禁用搜索,该值设为false
同样,此操作也需要开发者在创建Docket逻辑分组对象时,通过Knife4j提供的工具对象OpenApiExtensionResolver将扩展属性进行赋值。具体的代码实现请参考禁用调试和自定义主页内容,我这里就不重复了。
版权归原作者 yololee_ 所有, 如有侵权,请联系我们删除。