SpringBoot中使用Knife4J的解决方案
作者:薛定谔的壳
knife4j是为Java MVC框架集成Swagger生成Api文档的增强解决方案。
knife4j的前身是swagger-bootstrap-ui,为了契合微服务的架构发展,由于原来swagger-bootstrap-ui采用的是后端Java代码+前端Ui混合打包的方式,在微服务架构下显的很臃肿,因此项目正式更名为knife4j。 knife4j官方网址:knife4j
一、引入依赖
Knife4J 官网:
https://doc.xiaominfo.com/
快速开始:https://doc.xiaominfo.com/docs/quick-start
<!--引入Knife4j的官方start包,Swagger2基于Springfox2.10.5项目--> <dependency> <groupId>com.github.xiaoymin</groupId> <!--使用Swagger2--> <artifactId>knife4j-spring-boot-starter</artifactId> <version>2.0.9</version> </dependency>
二、创建配置类
创建config包,在其中新建一个配置类:
@Configuration @EnableSwagger2WebMvc public class Knife4jConfiguration { @Bean(value = "dockerBean") public Docket dockerBean() { //指定使用Swagger2规范 Docket docket=new Docket(DocumentationType.SWAGGER_2) .apiInfo(new ApiInfoBuilder() //描述字段支持Markdown语法 .description("# 写一个简要的描述") .termsOfServiceUrl("https://doc.xiaominfo.com/") .contact("可以写作者的信息") .version("1.0") .build()) //分组名称 .groupName("用户服务") .select() //这里指定Controller扫描包路径 .apis(RequestHandlerSelectors.basePackage("com.xueou.boot.controller")) .paths(PathSelectors.any()) .build(); return docket; } }
- 最重要的配置还是:指定
- Controller扫描包路径
contact
官方是弃用了直接传字符串的这个设置方法,改用传入一个Contact
类,看一下源码可以发现该类的结构(内容更丰富了:姓名、邮箱、URL连接)
三、常用注解
3-1 @Api
@Api
注解,添加在 Controller
类上,标记它作为 Swagger 文档资源。
3-1-1 @Api 注解的常用属性,如下:
tags
属性:用于控制 API 所属的标签列表。[] 数组,可以填写多个。- 可以在一个
Controller
上的@Api
的tags
属性,设置多个标签,那么这个Controller
下的 API 接口,就会出现在这两个标签中。 - 如果在多个
Controller
上的@Api
的tags
属性,设置一个标签,那么这些Controller
下的 API 接口,仅会出现在这一个标签中。 - 本质上,
tags
就是为了分组 API 接口,和Controller
本质上是一个目的。所以绝大数场景下,我们只会给一个Controller
一个唯一的标签。
3-1-2 @Api 注解的不常用属性,如下:
produces
属性:请求请求头的可接受类型( Accept )。如果有多个,使用 , 分隔。consumes
属性:请求请求头的提交内容类型( Content-Type )。如果有多个,使用 , 分隔。protocols
属性:协议,可选值为 “http”、“https”、“ws”、“wss” 。如果有多个,使用 , 分隔。authorizations
属性:授权相关的配置,[] 数组,使用 @Authorization 注解。hidden
属性:是否隐藏,不再 API 接口文档中显示。
@Api 注解的废弃属性,不建议使用,有 value、description、basePath、position 。
3-2 @ApiOperation
@ApiOperation
注解,添加在 Controller 方法上,标记它是一个 API 操作。
3-2-1 @ApiOperation 注解的常用属性,如下:
value
属性:API 操作名。notes
属性:API 操作的描述。
3-2-2 @ApiOperation 注解的不常用属性,如下:
tags
属性:和 @API 注解的 tags 属性一致。nickname
属性:API 操作接口的唯一标识,主要用于和第三方工具做对接。httpMethod
属性:请求方法,可选值为 GET、HEAD、POST、PUT、DELETE、OPTIONS、PATCH 。因为 Swagger 会解析 SpringMVC 的注解,所以一般无需填写。produces
属性:和 @API 注解的 produces 属性一致。consumes
属性:和 @API 注解的 consumes 属性一致。protocols
属性:和 @API 注解的 protocols 属性一致。authorizations
属性:和 @API 注解的 authorizations 属性一致。hidden
属性:和 @API 注解的 hidden 属性一致。response
属性:响应结果类型。因为 Swagger 会解析方法的返回类型,所以一般无需填写。responseContainer
属性:响应结果的容器,可选值为 List、Set、Map 。responseReference
属性:指定对响应类型的引用。这个引用可以是本地,也可以是远程。并且,当设置了它时,会覆盖 response 属性。说人话,就是可以忽略这个属性,哈哈哈。responseHeaders
属性:响应头,[] 数组,使用 @ResponseHeader 注解。code
属性:响应状态码,默认为 200 。extensions
属性:拓展属性,[] 属性,使用 @Extension 注解。ignoreJsonView
属性:在解析操作和类型,忽略 JsonView 注释。主要是为了向后兼容。
@ApiOperation 注解的废弃属性,不建议使用,有 position 。
3-3 @ApiImplicitParam
@ApiImplicitParam
注解,添加在 Controller 方法上,声明每个请求参数的信息。
3-3-1 @ApiImplicitParam 注解的常用属性,如下:
name
属性:参数名。value
属性:参数的简要说明。required
属性:是否为必传参数。默认为 false 。dataType
属性:数据类型,通过字符串 String 定义。dataTypeClass
属性:数据类型,通过 dataTypeClass 定义。在设置了dataTypeClass 属性的情况下,会覆盖 dataType 属性。推荐采用这个方式。paramType
属性:参数所在位置的类型。有如下 5 种方式:
"path"
值:对应 SpringMVC 的 @PathVariable 注解。
【默认值】"query"
值:对应 SpringMVC 的 @PathVariable 注解。"body"
值:对应 SpringMVC 的 @RequestBody 注解。"header"
值:对应 SpringMVC 的 @RequestHeader 注解。"form"
值:Form 表单提交,对应 SpringMVC 的 @PathVariable 注解。
绝大多数情况下,使用 “query” 值这个类型即可。
example
属性:参数值的简单示例。examples
属性:参数值的复杂示例,使用 @Example 注解。
3-3-2 @ApiImplicitParam 注解的不常用属性,如下:
defaultValue
属性:默认值。allowableValues
属性:允许的值。如果要设置多个值,有两种方式:
数组方式,即 {value1, value2, value3} 。例如说,{1, 2, 3} 。
范围方式,即 [value1, value2]
或 [value1, value2)
。例如说 [1, 5] 表示 1 到 5 的所有数字。如果有无穷的,可以使用 (-infinity, value2]
或 [value1, infinity)
。
allowEmptyValue
属性:是否允许空值。allowMultiple
属性:是否允许通过多次传递该参数来接受多个值。默认为 false 。type
属性:搞不懂具体用途,对应英文注释为 Adds the ability to override the detected type 。readOnly
属性:是否只读。format
属性:自定义的格式化。collectionFormat
属性:针对 Collection 集合的,自定义的格式化。
当我们需要添加在方法上添加多个 @ApiImplicitParam 注解时,可以使用 @ApiImplicitParams 注解中添加多个。
3-4 @ApiModel
@ApiModel
注解,添加在 POJO 类,声明 POJO 类的信息。而在 Swagger 中,把这种 POJO 类称为 Model 类。所以,我们下文就统一这么称呼。
3-4-1 @ApiModel 注解的常用属性,如下:
value
属性:Model 名字。description
属性:Model 描述。
3-4-2 @ApiModel 注解的不常用属性,如下:
parent
属性:指定该 Model 的父 Class 类,用于继承父 Class 的 Swagger 信息。subTypes
属性:定义该 Model 类的子类 Class 们。discriminator
属性:搞不懂具体用途,对应英文注释为 Supports model inheritance and polymorphism.reference
属性:搞不懂具体用途,对应英文注释为 Specifies a reference to the corresponding type definition, overrides any other metadata specified
3-5 @ApiModelProperty
@ApiModelProperty
注解,添加在 Model 类的成员变量上,声明每个成员变量的信息。
3-5-1 @ApiModelProperty 注解的常用属性,如下:
value
属性:属性的描述。dataType
属性:和 @ApiImplicitParam 注解的 dataType 属性一致。不过因为 @ApiModelProperty 是添加在成员变量上,可以自动获得成员变量的类型。required
属性:和 @ApiImplicitParam 注解的 required 属性一致。example
属性:@ApiImplicitParam 注解的 example 属性一致。
3-5-2 @ApiModelProperty 注解的不常用属性,如下:
name
属性:覆盖成员变量的名字,使用该属性进行自定义。- allowableValues 属性:和 @ApiImplicitParam 注解的 allowableValues 属性一致。
position
属性:成员变量排序位置,默认为 0 。hidden
属性:@ApiImplicitParam 注解的 hidden 属性一致。accessMode
属性:访问模式,有 AccessMode.AUTO、AccessMode.READ_ONLY、AccessMode.READ_WRITE 三种,默认为 AccessMode.AUTO 。reference
属性:和 @ApiModel 注解的 reference 属性一致。- allowEmptyValue 属性:和 @ApiImplicitParam 注解的 allowEmptyValue 属性一致。
extensions
属性:和 @ApiImplicitParam 注解的 extensions 属性一致。
@ApiModelProperty 注解的废弃属性,不建议使用,有 readOnly 。
3-6 @ApiResponse
在大多数情况下,我们并不需要使用 @ApiResponse 注解,因为我们会类似 UserController#get(id) 方法这个接口,返回一个 Model 即可。
@ApiResponse
注解,添加在 Controller 类的方法上,声明每个响应参数的信息。@ApiResponse
注解的属性,基本已经被@ApiOperation
注解所覆盖,如下:message
属性:响应的提示内容。code
属性:和 @ApiOperation 注解的 code 属性一致。response
属性:和 @ApiOperation 注解的 response 属性一致。reference
属性:和 @ApiOperation 注解的 responseReference 属性一致。responseHeaders
属性:和 @ApiOperation 注解的 responseHeaders 属性一致。responseContainer
属性:和 @ApiOperation 注解的 responseContainer 属性一致。examples
属性:和 @ApiOperation 注解的 examples 属性一致。
当我们需要添加在方法上添加多个
@ApiResponse
注解时,可以使用@ApiResponses
注解中添加多个。
四、配置JavaBean
主要用于返回参数、或是接收参数的时候进行说明。
@Getter @Setter @ToString @NoArgsConstructor @ApiModel(value = "轮播图对象", description = "") public class Banner implements Serializable { @ApiModelProperty(value = "id", example = "1") @TableId(value = "id", type = IdType.AUTO) private Integer id; @ApiModelProperty(value = "图像链接", example = "https://xxx/xxx.png") private String imgUrl; @ApiModelProperty(value = "标题", example = "这是一个标题哟~") private String title; }
我自己用的时候,又封装了一层,设置了几个JavaBean用于包装返回的响应结果:
分别用于返回单个数据、数据列表,同时附带上状态码和说明信息。
@Data @ToString @AllArgsConstructor @NoArgsConstructor public abstract class RBean { @ApiModelProperty(value = "响应码", position = 0, example = "200", notes = "200: 成功;500:失败;") private Integer code; @ApiModelProperty(value = "响应说明", position = 1, example = "xx数据获取成功。") private String msg; } // ===================== @EqualsAndHashCode(callSuper=true) @Data @ToString @AllArgsConstructor @NoArgsConstructor public class ROneBean<T> extends RBean { @ApiModelProperty(value = "数据项", position = 2) private T data; } // ======================= @EqualsAndHashCode(callSuper=true) @Data @ToString @AllArgsConstructor @NoArgsConstructor public class RListBean<T> extends RBean{ @ApiModelProperty(value = "数据列表", position = 2) private List<T> data; }
五、配置Controller
潦草的写几个接口
@Api(tags = "首页模块") @RestController public class IndexController { @Resource IBannerService iBannerService; @ApiOperation(value = "域名直接转接口文档", hidden = true) @GetMapping("/") public void toDoc(HttpServletResponse response) throws IOException { response.sendRedirect("/doc.html"); } @ApiOperation("新增轮播图数据") @PostMapping("/addBanners") public void putBanner(@RequestBody Banner banner){ // ...... } @ApiOperation("查询一个具体轮播图") @ApiImplicitParams({ @ApiImplicitParam(name = "title",value = "标题",required = true,example = "小白菜"), @ApiImplicitParam(name = "date",value = "时间",required = true,example = "2022") }) @GetMapping("/searchOneBanner") public ROneBean<Banner> searchOneBanner(@RequestParam(name = "title",defaultValue = "") String name, @RequestParam(name = "date", defaultValue = "") String address){ ROneBean<Banner> resp = new ROneBean<>(); // ... return null } @ApiOperation("获取轮播图数据") @GetMapping("/getBanners") public RListBean<Banner> getBanners(){ RListBean<Banner> resp = new RListBean<>(); List<Banner> banners = iBannerService.list(); if(banners.isEmpty()){ resp.setCode(200); resp.setMsg("轮播图数据为空。"); }else{ resp.setCode(200); resp.setMsg("获取轮播图数据成功"); resp.setData(banners); } return resp; } }
六、接口文档预览
到此这篇关于SpringBoot中使用Knife4J的文章就介绍到这了,更多相关SpringBoot 使用Knife4J内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!