简单理解——代写接口文档的框架,可跟随接口修改实时更新。
Open API 格式:REST API 的描述格式,可使用 YAML 或 JSON 格式来编写。Open API 的描述范围:
Swagger :一套围绕 Open API 规范构建的一款 RESTful 接口的文档在线自动生成和功能测试 API。将相关信息通过 YAML/JSON 格式存储在描述文件中,再通过描述文件去更新接口文档。其工具组包:
Springfox:Swagger 在遇到版本迭代的时候还需要更改描述文件,但 Springfox 则优化了此过程,会根据代码实时生成文档。通过注解的方式将 Swagger 集成在代码中。
依赖:
web 项目
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
springfox 依赖,要一次性导入下面两个,版本要对应
<dependency>
<groupId>io.springfoxgroupId>
<artifactId>springfox-swagger2artifactId>
<version>2.9.2<version>
dependency>
<dependency>
<groupId>io.springfoxgroupId>
<artifactId>springfox-swagger-uiartifactId>
<version>2.9.2<version>
dependency>
注解:
启动类注解:
@EnableSwagger2 // 开启 swagger2 相关技术,扫描当前类所在包及其子包中的注解
@SpringBootApplication
控制类:
@RestController
public class SwaggerController {
@GetMapping("/get")
public String getStr(String str) {
return "SELECT " + str;
}
@PostMapping("/post")
public String postStr(String str) {
return "CREATE " + str;
}
@PutMapping("/put")
public String putStr(String str) {
return "UPDATE " + str;
}
@PatchMapping("/patch")
public String patchStr(String str) {
return "UPDATE " + str;
}
@DeleteMapping("/delete")
public String deleteStr(String str) {
return "DELETE " + str;
}
}
运行代码,访问 http://127.0.0.1:8080/swagger-ui.html,这里可能会遇到以下的报错:
启动项目遇到报错:java: 警告: 源发行版 17 需要目标发行版 17
解决方案:https://blog.csdn.net/weixin_44299027/article/details/120848738
启动项目遇到报错:类文件具有错误的版本 61.0, 应为 52.0
解决方案:spring6.0 开始 jdk 要求17以上才行,要么升级 JDK,要么降低 spring 版本。
我选择降低 spring 版本:
- https://mvnrepository.com/ 查看 spring-boot-starter-parent 的版本号
- 选择 3 以下的版本号,修改 Maven 依赖 spring-boot-starter-parent
启动项目遇到报错:Failed to start bean ‘documentationPluginsBootstrapper’;
解决方案:springboot 升级到 2.6.0之后,swagger版本和springboot出现了不兼容情况,要么降低 springboot 版本,要么配置spring.mvc.pathmatch.matching-strategy=ant_path_matcher
- A.降低 springboot 版本不再做赘述(可降低至 2.5 以下就绝对没问题);
- B.配置1:① 启动类加上注解
@EnableWebMvc;② 配置文件加上spring.mvc.pathmatch.matching-strategy=ant_path_matcher;- C.配置1不生效情况:参考:https://blog.csdn.net/weixin_39792935/article/details/122215625
- D.当上述三种解决方案都不生效的情况下,我采用的终极解决方案:降低 Springboot 版本(2.5.6),并采用 C 方案的配置,然后访问 http://127.0.0.1:8080/swagger-ui.html
访问页面为空:
解决方案:启动类加上注解@EnableOpenApi,并访问 http://localhost:8080/swagger-ui/index.html
解决无法访问的问题:
修改配置文件 application.properties
spring.mvc.pathmatch.matching-strategy=ant_path_matcher
新增配置类:
package com.chenjy.swagger.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
/**
* @Desc 解决高版本无法兼容 swagger2 的问题
* 如此配置之后,就可通过 http://127.0.0.1:8080/doc.html 去访问 swagger-ui.html
*/
@Configuration
public class WebMvcConfigurer extends WebMvcConfigurationSupport {
/**
* 发现如果继承了WebMvcConfigurationSupport,则在yml中配置的相关内容会失效。 需要重新指定静态资源
*/
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/**").addResourceLocations(
"classpath:/static/");
registry.addResourceHandler("swagger-ui.html", "doc.html").addResourceLocations(
"classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**").addResourceLocations(
"classpath:/META-INF/resources/webjars/");
super.addResourceHandlers(registry);
}
}
降低 springboot 版本到 2.5.6
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>2.5.6version>
<relativePath/>
parent>
访问界面如下图,可以从中看到我们写的接口:

扫描项目中(启动类同级目录及其子目录中)的所有控制器(默认是控制器) 中的 @GetMapping/@RequestMapping(method = {RequestMethod.GET}) 系列的注解,然后去解析注解对应的映射地址以及注解约束的请求方式(GET、POST、DELET…,默认为 GET)。点击具体方法可看详细的请求信息:

可点击 Try it out 测试一下:

package com.chenjy.swagger.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
@Configuration
public class SwaggerConfigurer {
/**
* @return Docket——Swagger 中的全局配置对象
*/
@Bean
public Docket docket() {
// DocumentationType.SWAGGER_2 告诉 Springfox 当前的 Swagger 版本是 Swagger2
Docket docket = new Docket(DocumentationType.SWAGGER_2);
// API 帮助文档的描述信息
ApiInfo apiInfo = new ApiInfoBuilder()
.title("Swagger 文档")// 文档标题
.description("Swagger :一套围绕 Open API 规范构建的一款 RESTful 接口的文档在线自动生成和功能测试 API。")// 描述信息
.version("1.0.1")// 版本号
.contact(
// name url email
new Contact("364.99°的文档", // 文档发布者名称
"https://blog.csdn.net/m0_54355172", // 文档发布者的网站地址
"2190826197@qq.com" // 文档发布者的邮箱
)
)
// 构建器模式
.build();
// 给 docket 上下文配置 API 描述信息
docket.apiInfo(apiInfo);
return docket;
}
}

在 docket 方法中添加以下配置:
docket
.select() // 获取 docket 中的选择器,如:扫描哪个包的注解
.apis(RequestHandlerSelectors.basePackage("com.chenjy.swagger.controller")); // 定义规则——包扫描规则

定义一个注解,标注当前接口不需要生成 Swagger 文档:
package com.chenjy.swagger.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.METHOD, ElementType.TYPE}) // 此注解用于描述 方法、类
@Retention(RetentionPolicy.RUNTIME)// 注释信息会在运行时被有效
public @interface NoSwagger {
// 自定义注解属性 @NoSwagger(value="")
String value() default "";
}
配置类使注解规则生效:
package com.chenjy.swagger.config;
import com.chenjy.swagger.annotation.NoSwagger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import static com.google.common.base.Predicates.not;
import static springfox.documentation.builders.RequestHandlerSelectors.withMethodAnnotation;
@Configuration
public class SwaggerConfigurer {
/**
* @return Docket——Swagger 中的全局配置对象
*/
@Bean
public Docket docket() {
// DocumentationType.SWAGGER_2 告诉 Springfox 当前的 Swagger 版本是 Swagger2
Docket docket = new Docket(DocumentationType.SWAGGER_2);
// API 帮助文档的描述信息
ApiInfo apiInfo = new ApiInfoBuilder()
.title("Swagger 文档")// 文档标题
.description("Swagger :一套围绕 Open API 规范构建的一款 RESTful 接口的文档在线自动生成和功能测试 API。")// 描述信息
.version("1.0.1")// 版本号
.contact(
// name url email
new Contact("364.99°的文档", // 文档发布者名称
"https://blog.csdn.net/m0_54355172", // 文档发布者的网站地址
"2190826197@qq.com" // 文档发布者的邮箱
)
)
// 构建器模式
.build();
// 给 docket 上下文配置 API 描述信息
docket.apiInfo(apiInfo);
Docket build = docket
.select() // 获取 docket 中的选择器,如:扫描哪个包的注解
.apis(
not( // 取反
withMethodAnnotation(NoSwagger.class) // 当方法上有注解的时候返回 true
)
)
.apis(RequestHandlerSelectors.basePackage("com.chenjy.swagger.controller")) // 定义规则——包扫描规则
.build();
return build;
}
}
注意: 这里需要重新 build 一次 Docket ,然后返回重新 build 之后的 docket,否则不会生效。
标注在接口方法上:
@NoSwagger
@PatchMapping("/patch")
public String patchStr(String str) {
return "UPDATE " + str;
}
重启项目,访问:

优化写法:
Docket build = docket
.select() // 获取 docket 中的选择器,如:扫描哪个包的注解
.apis(
and(
not( // 取反
withMethodAnnotation(NoSwagger.class) // 当方法上有注解的时候返回 true
),
RequestHandlerSelectors.basePackage("com.chenjy.swagger.controller")
)
)
.build();
return build;
注意:
and 和 not 都是 com.google.common.base.Predicates 中的静态方法;withMethodAnnotation 是 springfox.documentation.builders.RequestHandlerSelectors 中的静态方法。springfox.documentation.builders.PathSelectors
只有路径前缀为 /test 的接口方法才会生成文档。
Docket build = docket
.select() // 获取 docket 中的选择器,如:扫描哪个包的注解
.paths(
PathSelectors.regex("/test/.*") // 使用正则表达式 . 任意字符 * 0个或多个
)
.build();
return build;
同时多种路径匹配规则: Predicates.or
.paths(
Predicates.or(
PathSelectors.regex("/test/.*"),
PathSelectors.regex("/.*")
)
)
@Api(tags = {"test 接口 API"})
tags 定义控制器别名,可以有多个值,有几个别名,文档中就有几个控制器目录。
@ApiOperation(value = "get 方法,执行查询操作", notes = "一个小 demo")

@ApiParam()
参数、方法、属性注解,常用来描述参数;
@PostMapping("/post")
public String postStr(
@ApiParam(name = "字符串", value = "用来输出的字符串", required = true) String str,
@ApiParam(name = "序列号", required = false) @RequestParam(defaultValue = "001", required = false)String num
) {
return "CREATE " + str + num;
}

@ApiIgnore
方法、属性注解,让此注解描述的方法或类型不生成 API 文档。
@ApiIgnore
@PutMapping("/put")
public String putStr(String str) {
return "UPDATE " + str;
}
@ApiImplicitParam
在方法上描述方法参数,只能描述一个参数。
@ApiImplicitParam(
name = "str", value = "一个字符串", required = true, paramType = "java.lang.String", dataType = "任意字符串"
)
@DeleteMapping("/delete")
public String deleteStr(String str, Integer num) {
return "DELETE " + str;
}
ApiImplicitParams
@ApiImplicitParams(value = {
@ApiImplicitParam( name = "str", value = "一个字符串", required = true, paramType = "java.lang.String", dataType = "任意字符串" ),
@ApiImplicitParam( name = "num", value = "一个整数")
})
@DeleteMapping("/delete")
public String deleteStr(String str, Integer num) {
return "DELETE " + str;
}
@ApiModel
描述实体类,当此实体类被作为返回类型用于 API 帮助文档中的接口方法中,此注解被解析。
@Data
@NoArgsConstructor
@AllArgsConstructor
@ApiModel( value = "一个实体类", description = "存储数据并返回")
public class TestDto {
private String name;
private Integer num;
}
@PatchMapping("/patch")
public TestDto patchStr(String str, Integer num) {
return new TestDto(str, num);
}
@ApiModelProperty
描述实体类的属性,要搭配 @ApiModel 使用。
@Data
@NoArgsConstructor
@AllArgsConstructor
@ApiModel( value = "一个实体类", description = "存储数据并返回")
public class TestDto {
@ApiModelProperty( value = "姓名", example = "张三", hidden = false)
private String name;
@ApiModelProperty( value = "序列号")
private Integer num;
}


注意:
@requestBody ;@requestBody (对于参数转化的配置必须统一)和 @requestParam 。