友情提醒:
先看目录,了解文章结构,点击目录可跳转到文章指定位置。
第一章、快速了解Swagger2
1.1)相关概念介绍
Swagger2是一个用于设计、构建和文档化Web API的工具。它允许开发人员定义API的结构、请求和响应格式,并生成交互式的API文档。开发人员在类上使用注解描述接口,Swagger直接在网页上生成和展示API,使得API的开发和维护更加简单和高效。
1.2)为什么使用Swagger2
①API文档自动生成:Swagger可以根据API的定义自动生成交互式的API文档,包括请求和响应的结构、参数说明等。
②统一API标准:Swagger提供了一种标准化的方式来描述API,使得团队成员之间可以统一接口文档标准,更好地理解和协作。
③减少沟通成本,方便接口测试和调试:通过Swagger生成的API文档,开发人员可以方便地测试和调试API,快速验证接口的正确性和可用性。
④可视化:Swagger生成的交互式API文档具有良好的可视化效果,开发人员可以更快地理解和使用API。
第二章、SpringBoot如何集成Swagger2
2.1)引入依赖
①只需要引入Swagger2依赖与SpringFox集成
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-boot-starter</artifactId>
<version>3.0.0</version>
<exclusions>
<exclusion>
<groupId>org.springframework.plugin</groupId>
<artifactId>spring-plugin-core</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework.plugin</groupId>
<artifactId>spring-plugin-metadata</artifactId>
</exclusion>
</exclusions>
</dependency>
2.2)创建配置类ConfigSwagger
2.2.1)类ConfigSwagger总体配置
②创建一个Swagger配置类,配置Swagger的基本信息和API文档的展示规则。
③在Spring Boot应用程序的启动类中使用注解@SpringBootApplication,启动SpringBoot应用程序时,将同时启用Swagger
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.ReflectionUtils;
import org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.spring.web.plugins.WebMvcRequestHandlerProvider;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
import java.lang.reflect.Field;
import java.util.List;
@Configuration
@EnableSwagger2 // 通过yaml中swagger2.enable控制是否加载swagger
@ConditionalOnProperty(prefix = "swagger2", value = "enable", havingValue = "true")
public class SwaggerConfig {
@Bean
public static BeanPostProcessor springfoxBeanPostProcessor() {
return new BeanPostProcessor() {
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof WebMvcRequestHandlerProvider) {
getHandlerMappings(bean).removeIf(m -> m.getPatternParser() != null);
}
return bean;
}
private List<RequestMappingInfoHandlerMapping> getHandlerMappings(Object bean) {
try {
Field field = ReflectionUtils.findField(bean.getClass(), "handlerMappings");//固定写法不用改
field.setAccessible(true);
return (List<RequestMappingInfoHandlerMapping>) field.get(bean);
} catch (IllegalAccessException e) {
throw new IllegalStateException(e);
}
}
};
}
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.basePackage("com.text.sh.controller"))//接口文档信息会根据配置的controller包位置生成
.paths(PathSelectors.any())
.build();
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.termsOfServiceUrl("admin api docs")
.description("")
.version("0.0.1")
.build();
}
}
2.2.2)Swagger配置详解:扫描Controller的三种方式
第一种基于包路径扫描:通过指定Controller所在的包路径来扫描并生成API文档。前面配的就是这种
@Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.basePackage("com.example.controllers"))
.build();
}
第二种基于路径扫描:通过指定特定路径来扫描符合该路径规则的Controller并生成API文档
@Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.ant("/api/**"))
.build();
}
第三种基于注解扫描:通过指定特定注解来扫描带有该注解的Controller并生成API文档。
1、基于类注解扫描:通过指定特定的类级别注解来扫描带有该注解的Controller并生成API文档。这样配置后可以扫描带有@RestController注解的类(也可以替换成Api.class去扫描@Api注解)
@Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.withClassAnnotation(RestController.class))//可以扫描带有@RestController注解的类(也可以替换成Api.class)
.build();
}
2、基于方法注解扫描:通过指定特定的方法级别注解来扫描带有该注解的Controller方法并生成API文档。这样配置后可以扫描带有@GetMapping注解(也可以替换成ApiOperation.class去扫描@ApiOperation注解)
@Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.withMethodAnnotation(GetMapping.class))//可以扫描带有@GetMapping注解(也可以替换成ApiOperation)
.build();
}
2.3.3)Swagger配置详解:APi文档信息
①termsOfServiceUrl是用来设置服务条款链接的属性。没有规范要求的话可以随便写个链接,但如果写一个真实有效的服务条款链接,别人就可以通过这个链接能够查看和了解相关的服务条款和使用规则
②description(“”):设置了API的描述信息。这个字段通常用于描述API的简要信息或用途。可以根据情况简略写一点信息,我这里写的空字符串。
③version(“0.0.1”):设置了API的版本号为"0.0.1"。这个字段用于标识API的版本信息。
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.termsOfServiceUrl("admin api docs")
.description("")
.version("0.0.1")
.build();
}
2.3)拦截器配置:在拦截器配置中排除Swagger请求
springboot的拦截器会拦截所有http请求,要在拦截器配置中添加条件来排除Swagger请求,可以通过拦截器的excludePathPatterns方法,添加请求的路径进行判断并排除Swagger请求。
WebMvcConfigurerAdapter 是自定义的拦截器类。
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new CustomInterceptor())
.addPathPatterns("/**")
.excludePathPatterns("/swagger-ui.html", "/v2/api-docs", "/swagger-resources/**", "/webjars/**");
}
}
2.4)访问Swagger U
启动Spring Boot应用程序后,访问一下链接即可查看生成的API文档和交互式界面,其中8080为SpringBoot程序端口号,根据实际情况更改。
http://localhost:8080/swagger-ui.html
或者:
http://localhost:8080/swagger-ui/index.html
第三章、Swagger UI 注解
3.1)Swagger注解介绍
注解 | 使用位置 | 解释 |
---|---|---|
@Api | 类上使用 | 标记一个类作为Swagger资源API,用于描述整个类的API信息。,如API的标题、描述、协议等。 |
@ApiOperation | 在方法上使用 | 用于描述一个API接口的操作信息,如HTTP方法(GET、POST等)、接口描述、响应类型等。 |
@ApiImplicitParam | 在方法上使用 | 用于描述API操作中的某个输入参数,但不包括在方法签名中(如URL参数、表单参数等)。可以单独使用,也可以配合@ApiImplicitParams使用。 |
@ApiImplicitParams | 方法上使用 | 允许多个@ApiImplicitParam对象的列表,用于一次性描述多个API操作中的输入参数。 |
@ApiModel | 类上使用 | 为Swagger模型提供额外信息,通常用于描述返回对象或请求对象的结构。 |
@ApiModelProperty | 字段上使用 | 添加和操作模型属性的数据,如属性的描述、是否必须、是否允许为空等。 |
@ApiResponse | 方法上使用 | 描述操作的一个可能响应,包括状态码、描述、响应内容等。通常与@ApiResponses一起使用。 |
@ApiResponses | 方法上使用 | 描述操作的所有可能响应,包含一个或多个@ApiResponse注解。 |
@ApiParam() | 方法参数上使用 | 用于描述方法的参数信息,如参数名、是否必需、参数描述等。主要用于描述URL路径参数或查询参数。 |
@ApiIgnore | 类、接口、枚举、方法、参数上使用 | 用于指定类、接口、枚举、方法、参数等不被Swagger生成文档。可以通过value属性提供忽略此参数/操作的原因的简要说明。 |
3.2)示例用法1:在model类上使用注解
使用@ApiModel和@ApiModelProperty来描述这个对象的结构和属性
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
@Data
@ApiModel(description = "用户信息模型")
public class User {
@ApiModelProperty(value = "用户ID", example = "12345")
private Long id;
@ApiModelProperty(value = "用户姓名", required = true, example = "张三")
private String name;
@ApiModelProperty(value = "用户年龄", required = true, example = "30")
private Integer age;
}
3.3)示例用法2
@Api
@ApiOperation
@ApiResponses
@ApiResponse
@RestController
@RequestMapping("/api/users")
@Api(tags = "用户管理API")
public class UserController {
@ApiOperation(value = "获取用户信息", notes = "根据用户ID获取用户详细信息")
@ApiResponses(value = {
@ApiResponse(code = 200, message = "成功获取用户信息"),
@ApiResponse(code = 404, message = "未找到用户")
})
@GetMapping("/{userId}")
public String getUserById(@PathVariable Long userId) {
return "User information for ID: " + userId;
}
@ApiOperation(value = "创建新用户", notes = "使用用户信息对象创建一个新用户")
@ApiResponses(value = {
@ApiResponse(code = 201, message = "用户创建成功"),
@ApiResponse(code = 400, message = "用户信息不合法")
})
@PostMapping
public String createUser(@RequestBody User user) {
// 实现将用户信息保存到数据库的逻辑
return "User created with name: " + user.getName() + " and age: " + user.getAge();
}
}
3.4)示例用法3
@Api
@ApiImplicitParams
@ApiImplicitParam
@ApiParam
@ApiIgnore
@RestController
@RequestMapping("/api/users")
@Api(tags = "用户管理API")
public class UserController {
@ApiOperation(value = "根据用户姓名搜索用户", notes = "使用用户姓名作为查询参数搜索用户")
@ApiImplicitParams({
@ApiImplicitParam(name = "name", value = "用户姓名", required = false, dataType = "string", paramType = "query")
})
@GetMapping("/search1")
// 注意:通常不需要同时使用@ApiImplicitParam和@RequestParam
// 如果你只使用@RequestParam,Swagger仍然能够识别并展示这个查询参数
public String searchUserByName(@RequestParam(required = false) String name) {
// 实现根据姓名搜索用户的逻辑
return "Searching for user with name: " + (name != null ? name : "not specified");
}
// 展示@ApiParam的用法(可能不是必需的)
@ApiOperation(value = "根据用户姓名和年龄搜索用户", notes = "这是一个示例方法,用于展示@ApiParam的用法")
@GetMapping("/search2")
public String searchUser(
//对于 @RequestParam、@PathVariable ,Swagger 通常能够自动捕获它们的元数据
//(如参数名、是否必需等),因此在这些情况下,@ApiParam 可能不是必需的
@ApiParam(value = "用户姓名", example = "John Doe") @RequestParam(required = false) String name,
@ApiParam(value = "用户年龄", example = "30") @RequestParam(required = false) Integer age) {
return "Searching for user with name: " + name + " and age: " + age;
}
// 展示@ApiIgnore的用法,不想在Swagger文档中暴露这个方法
@ApiIgnore
@GetMapping("/ignore")
public String ignoreThisMethod() {
// 这个方法不会被Swagger文档包含
return "This method is ignored by Swagger";
}
}