文章目录
- 前言
- 技术积累
- 何为swagger
- 何为knife4j
- Swagger2与Swagger3注解的主要区别
- springboot整合swagger及knife4j
- 导入maven依赖
- yaml配置
- 编写配置类
- 编写实体和接口
- 效果展示
前言
对于一个有着资深后端搬砖经验的人来说,最重要的事情就是写API文档了。一个好的API文档不仅仅能够提供给测试人员编写测试用例,也能够直接给前端使用查阅,可以避免很多在系统集成过程中的问题。这不,最近在整合架构的时候留意到了swagger和knife4j。本身swagger提供的web界面可以很好的调试和查阅,现在加上knife4j的API文档自动生成功能,简直不要太好。那么,今天就分享一期springboot整合swagger及knife4j吧!各位大大敬请鉴赏。
技术积累
何为swagger
首先OpenApi是业界真正的 api 文档标准,其是由 Swagger 来维护的,并被linux列为api标准,从而成为行业标准。
swagger 是一个 api 文档维护组织,后来成为了 Open API 标准的主要定义者,现在最新的版本为17年发布的 Swagger3(Open Api3)。国内绝大部分人还在用过时的swagger2(17年停止维护并更名为swagger3)swagger2的包名为 io.swagger,而swagger3的包名为 io.swagger.core.v3。
何为knife4j
Knife4j就是一个接口文档工具,可以看作是Swagger的升级版,但是界面比Swagger更好看,功能更丰富。早期,swagger-boostrap-ui是1.x版本,如今swagger-bootsrap-ui到2.x,同时也更改名字Knife4j,适用于单体和微服务项目。
Swagger2与Swagger3注解的主要区别
Swagger3基于OpenAPI Specification 3.0,这个新版本的规范带来了更多的灵活性和表达力。
以下是Swagger2和Swagger3注解的一些主要区别:
通用注解
Swagger2: 使用@Api来注解控制器类,表明该类的路径应该被Swagger文档化。
Swagger3: 不再需要@Api注解。Swagger3使用更自然的方式来扫描类路径,自动包含所有的控制器。
API信息和描述
Swagger2: 通过@ApiInfo和@ApiOperation注解来提供API的信息和操作描述。
Swagger3: 使用@Tag注解来替代@Api,并且通过@Operation注解来提供操作的描述。
路径和操作注解
Swagger2: 使用@ApiOperation来描述一个HTTP操作,@ApiImplicitParam和@ApiImplicitParams用于描述参数。
Swagger3: 引入了@Operation注解来描述HTTP操作,@Parameter注解用于描述参数。
参数注解
Swagger2: 参数注解是通过@ApiParam或@ApiImplicitParam来描述。
Swagger3: 使用@Parameter注解来描述参数,它提供了更丰富的属性,如schema、example和content。
请求体和响应体注解
Swagger2: 使用@ApiModel和@ApiModelProperty注解来描述请求和响应的数据模型。
Swagger3: 引入了@Schema注解来描述数据模型,提供了更多的细节和配置选项。
安全和授权注解
Swagger2: 使用@ApiResponses、@ApiResponse、@ApiOperation等注解来描述响应和错误码。
Swagger3: @ApiResponse注解仍然存在,但是现在可以包含更多的信息,如媒体类型和例子。
springboot整合swagger及knife4j
导入maven依赖
<!--Swagger-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-boot-starter</artifactId>
<version>3.0.0</version>
</dependency>
<!--knife4j -->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-boot-starter</artifactId>
<version>3.0.3</version>
</dependency>
yaml配置
knife4j 3.* 的版本会跟 springboot 3.6.* 版本冲突,以下是解决冲突的办法
在yaml文件中加入以下配置即可
server:
port: 8888
spring:
profiles:
active: dev
mvc:
pathmatch:
# Springfox使用的路径匹配是基于AntPathMatcher的,而Spring Boot 2.6.X使用的是PathPatternMatcher
matching-strategy: ant_path_matcher
knife4j:
enable: true #开启增强配置
basic: #基本的登录认证
enable: true
username: admin
password: 123456
编写配置类
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.core.env.Profiles;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.oas.annotations.EnableOpenApi;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
/**
* SwaggerConfig
* @author senfel
* @version 1.0
* @date 2024/3/27 16:04
*/
@Configuration
@EnableOpenApi
public class SwaggerConfig {
@Bean
public Docket initDocket(Environment env) {
//设置要暴漏接口文档的配置环境
//设置要显示的Swagger环境
Profiles profile = Profiles.of("test","dev");
//获取项目的环境:
//通过environment.acceptsProfiles判断是否处在自己设定的环境当中
boolean flag = env.acceptsProfiles(profile);
return new Docket(DocumentationType.OAS_30)
.apiInfo(apiInfo())
//是否启动swagger 默认为true ,如果为false,则Swagger不能再浏览器中访问
.enable(flag)
.select()
//RequestHandlerSelectors,配置要扫描接口的方式
// .apis(RequestHandlerSelectors.any()):扫描全部
// .apis(RequestHandlerSelectors.none()):不扫描
// .apis(RequestHandlerSelectors.withClassAnnotation(RestController.class)):扫描类上的注解,参数是一个注解的反射对象
// .apis(RequestHandlerSelectors.withMethodAnnotation(GetMapping.class)):扫描方法上的注解
//指定要扫描的包
.apis(RequestHandlerSelectors.basePackage("com.example.ccedemo.controller"))
//paths()过滤什么路径(url)
// .paths(PathSelectors.ant("/pm/**")) 就是在localhost:8080/pm后面的路径
// .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
//不过滤
.paths(PathSelectors.any())
.build();
//右上角 组(有几个Docket,有几个组)
// .groupName();
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("接口文档")
.description("接口文档")
.contact(new Contact("senfel", "", "XXXX@sina.cn"))
.version("V1.0")
.license("Apache 2.0")
.build();
}
}
编写实体和接口
import io.swagger.annotations.ApiModel;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* Dept
* @author senfel
* @version 1.0
* @date 2024/3/27 16:23
*/
@Data
@ApiModel(description = "部门")
@AllArgsConstructor
@NoArgsConstructor
public class Dept {
@Schema(description = "主键")
private Long id;
@Schema(description = "部门名")
private String name;
}
import com.example.ccedemo.entity.Dept;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.http.ResponseEntity;
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;
/**
* DeptController
* @author senfel
* @version 1.0
* @date 2024/3/27 16:25
*/
@RestController
@Api(tags = "部门管理")
@RequestMapping("/sys/")
public class DeptController {
/**
* 获取部门
* @param dept
* @author senfel
* @date 2024/3/27 16:34
* @return org.springframework.http.ResponseEntity<com.example.ccedemo.entity.Dept>
*/
@GetMapping("/getDept")
@ApiOperation(value = "获取部门")
public ResponseEntity<Dept> get(@RequestParam Dept dept){
System.err.println(dept.getName());
return ResponseEntity.ok(dept);
}
}
效果展示
浏览器访问http://localhost:8888/swagger-ui/即可访问到swagger3初始页面
输入配置文件中的用户名和密码
浏览器访问http://localhost:8888/doc.html即可访问knife4j初始页面