目录
产生背景
-
随着互联网技术的发展,现在的网站架构基本都由原来的后端渲染,变成了前后端分离的形态,而且前 端技术和后端技术在各自的道路上越走越远。前端和后端的唯一联系,变成了 API 接口,所以 API 文档 变成了前后端开发人员联系的纽带,变得越来越重要。
-
那么问题来了,随着代码的不断更新,开发人员在开发新的接口或者更新旧的接口后,由于开发任务的 繁重,往往文档很难持续跟着更新,Swagger 就是用来解决该问题的一款重要的工具,对使用接口的人 来说,开发人员不需要给他们提供文档,只要告诉他们一个 Swagger 地址,即可展示在线的 API 接口 文档,除此之外,调用接口的人员还可以在线测试接口数据,同样地,开发人员在开发接口时,同样也 可以利用 Swagger 在线接口文档测试接口数据,这给开发人员提供了便利。
官方解释:
Swagger是全球最大的OpenAPI规范(OAS)API开发工具框架,支持从设计和文档到测试和部署的整个API生命周期的开发。Swagger是⼀个⽤于⽣成服务器接⼝的规范性⽂档、并且能够对接⼝进⾏测试的⼯具。
简单来说:Swagger是一个规范和完整的框架,用于生成、描述、调用和可视化Restful风格的web服务。
作用
- 接口的文档在线自动生成
- 功能测试
SpringBoot3整合Swagger注意事项
SpringBoot3+jdk17的情况下,swagger的V2和V3都是不行的。这里使用spring官方出品的springdoc-openapi。在使用springdoc-openapi的时候也有很多坑,首先springdoc-openapi的v1.x.x版本也是不行的,springdoc-openapi的版本必须是v2.x.x以上。
swagger3 常用注解
注解SpringBoot3 版本 | 替换旧注解 SpringBoot2 版本 | 描述 |
---|---|---|
@Tag | @Api | 用于标注一个Controller(Class)。在默认情况下,Swagger-Core只会扫描解析具有@Api注解的类,而会自动忽略其他类别资源(JAX-RS endpoints,Servlets等等)的注解。 |
@Operation | @ApiOperation | 用于对一个操作或HTTP方法进行描述。具有相同路径的不同操作会被归组为同一个操作对象。不同的HTTP请求方法及路径组合构成一个唯一操作。 |
@Parameter | @ApiParam | @Parameter作用于请求方法上,定义api参数的注解。 |
@Parameters、@Parameter | @ApiImplicitParams、@ApiImplicitParam | 都可以定义参数 (1)@Parameters:用在请求的方法上,包含一组参数说明 (2)@Parameter:对单个参数的说明 |
io.swagger.v3.oas.annotations新包中的@ApiResponses、@ApiResponse | 旧包io.swagger.annotations中的@ApiResponses、@ApiResponse | 进行方法返回对象的说明。 |
@Schema | @ApiModel、@ApiModelProperty | @Schema用于描述一个Model的信息(这种一般用在post创建的时候,使用@RequestBody这样的场景)。 |
SpringBoot3.x整合Swagger
1.创建工程(jdk:17,boot:3.2.4)
项目结构:
2.引入pom依赖
<!-- openAPI包,替换 Swagger 的 SpringFox -->
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
<version>2.2.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
3.application.yml添加配置
spring:
mvc:
pathmatch:
matching-strategy: ant_path_matcher
4.添加swagger3.0配置
package com.example.config;
import io.swagger.v3.oas.models.ExternalDocumentation;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Info;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author: Susheng
* @datetime: 2024/3/26
* @desc:
*/
@Configuration
public class OpenAPIConfig {
@Bean
public OpenAPI openAPI() {
return new OpenAPI()
.info(new Info()
.title("接口文档标题")
.description("SpringBoot3 集成 Swagger3接口文档")
.version("v1"))
.externalDocs(new ExternalDocumentation()
.description("项目API文档")
.url("/"));
}
}
5.控制器层(Controller)
package com.example.controller;
import com.example.model.SwaggerApiModel;
import io.swagger.v3.oas.annotations.Hidden;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.web.bind.annotation.*;
/**
* @author: zjl
* @datetime: 2024/3/26
* @desc:
*/
@Tag(name = "控制器:测试Swagger3", description = "描述:测试Swagger3")
@RestController
public class SwaggerController {
@Operation(summary = "测试Swagger3注解方法Get")
@Parameters({@Parameter(name = "id",description = "编码"),
@Parameter(name = "headerValue",description = "header传送内容")})
@ApiResponses({
@ApiResponse(responseCode = "200", description = "请求成功"),
@ApiResponse(responseCode = "400", description = "请求参数没填好"),
@ApiResponse(responseCode = "401", description = "没有权限"),
@ApiResponse(responseCode = "403", description = "禁止访问"),
@ApiResponse(responseCode = "404", description = "请求路径没有或页面跳转路径不对")
})
@GetMapping(value = "/swagger/student")
public Object getStudent(@RequestParam @Parameter(example = "2") String id,
@RequestHeader @Parameter(example = "2") String headerValue){
return id;
}
@Operation(summary = "测试Swagger3注解方法Post")
@ApiResponses({
@ApiResponse(responseCode = "200", description = "请求成功"),
@ApiResponse(responseCode = "400", description = "请求参数没填好"),
@ApiResponse(responseCode = "401", description = "没有权限"),
@ApiResponse(responseCode = "403", description = "禁止访问"),
@ApiResponse(responseCode = "404", description = "请求路径没有或页面跳转路径不对")
})
@PostMapping(value = "/swagger/student", produces = "application/json")
public SwaggerApiModel updateStudent(@RequestBody SwaggerApiModel model){
return model;
}
/**
* swagger 不暴漏该 api,通过@Hidden隐藏
* 但是仍然可以访问
* @return
*/
@Hidden
@GetMapping(value = "/swagger/hiddenApi")
public String hiddenApi(){
return "hiddenApi";
}
/**
* swagger 暴漏该 api,没有配置@Hidden会展示
* @return
*/
@GetMapping(value = "/swagger/noHiddenApi")
public String noHiddenApi(){
return "noHiddenApi";
}
}
6.模型层(Model)
package com.example.model;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.io.Serializable;
/**
* @author: zjl
* @datetime: 2024/3/26
* @desc:
*/
@Data
@Schema(description= "学生信息")
public class SwaggerApiModel implements Serializable {
@Schema(description = "主键ID", required = true, example = "1")
private Long id;
@Schema(description = "手机号", required = true)
private String phonenum;
@Schema(description = "密码", required = true)
private String password;
@Schema(description = "年龄", required = true)
private Integer age;
}
7.启动并测试
启动服务后,首先通过浏览器打开链接http://localhost:9090/swagger-ui/index.html
【Get请求接口】/swagger/student接口详情
-
入参
-
响应模板
-
接口测试
-
接口测试结果