前言
在前后端分离的开发模式下,两边的开发人员如何快速沟通?后端开发者将功能做出来之后,如何告知前端工作者?写个API文档?
API升级时,如何维护API文档?再搞一个?No!效率太慢了,不适合快速开发的场景。
这些情况下,swagger你值得拥有!!!
swagger能和和spring完美结合,自动生成线上API,接口开发完毕,API也就搞定了。这时候前端工作者要API,直接告诉他个网址就好了!!!
正式开工
1 引入swagger2的依赖
<!-- swagger支持 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<!--API文档显示UI-->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>swagger-bootstrap-ui</artifactId>
<version>1.9.2</version>
</dependency>
2 编写一个Swagger配置类(目的是生成那些接口的文档)
配置步骤
- 新建一个swagger包
- 新建一个SwaggerConfig类
package com.zyu.boot.demo.swagger;
import io.swagger.annotations.ApiOperation;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
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 springfox.documentation.swagger2.annotations.EnableSwagger2;
/**
* swagger配置类
*/
@ConditionalOnProperty(name = "debugSwitch", havingValue = "true")
@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Bean
public Docket DemoRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
.groupName("Test Api")
.select()
// 扫描指定包中的swagger注解
// .apis(RequestHandlerSelectors.basePackage(""))
/*
* 重要的两个方法: apis():指定要生成文档的接口包基本路径 paths():指定针对哪些请求生成接口文档
* 参考官方资料:http://www.baeldung.com/swagger-2-documentation-for-spring-rest-api
*/
// 扫描所有有注解的api,用这种方式更灵活
.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
// .apis(RequestHandlerSelectors.any())
.paths(PathSelectors.any()).build().apiInfo(apiInfo());
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder().title("SpringBoot Demo RESTful APIs").
description("测试接口").
termsOfServiceUrl("#").
contact(new Contact("zyu", "#", "zyu@zyu.com")).
version("1.0.0").build();
}
}
解释说明
- @ConditionalOnProperty(name = “debugSwitch”, havingValue = “true”):API文档通常情况下只能在开发环境下使用,所以线上版不应该有这个入口。只需要在类上标注ConditionalOnProperty注解,当在yml中配置debugSwitch为true时,spring才会扫描该配置类。
- @Configuration:以配置类的形式将swagger配置信息加载到spring容器中
- @EnableSwagger2:表示开启Swagger功能,不标注该标签,swagger不能正常工作
- ApiInfo:Api的简要说明(配置的信息会显示在页面上)
- Docket:可以理解为API的正文(该扫描哪些接口,在该对象中配置)
扫描接口的方式(RequestHandlerSelectors+PathSelectors)
-RequestHandlerSelectors:可以理解为类选择器,主要有两种,一种是基于包基本路径(basePackage)扫描,一种是基于方法注解扫描(methodAnnotation)。两种方式代码中都有演示到,个人喜欢用基于注解的形式,较为灵活
-PathSelectors:可以理解为路径选择器,支持的主要有any、none、regex、ant,简单讲就是全选、全不选、正则。
3 在测试类上进行标注(使用@ApiOperation)
@RestController
public class TestController {
@ApiOperation(value = "测试接口", notes = "测试使用swagger")
@ApiImplicitParams({
@ApiImplicitParam(name = "name", value = "姓名", required = true, paramType = "query"), })
@GetMapping("/sayHello")
public String sayHello(@Param("name") String name) {
return "hello," + name;
}
}
4 配置yml文件
#表示调试状态下,即开发环境
debugSwitch: true
5 启动项目,访问以下路径
http://localhost:8080/boot/doc.html(注意是项目路径+doc.html)
- 主页截图
- 离线文档
- 调试sayHello接口
6 其他Swagger相关的注解
-
@Api:用在类上,说明该类的作用 @ApiOperation:用在方法上,说明方法的作用
-
@ApiImplicitParams:用在方法上包含一组参数说明
-
@ApiImplicitParam:用在@ApiImplicitParams注解中,指定一个请求参数的各个方面
- paramType:参数放在哪个地方
header–>请求参数的获取:@RequestHeader
query–>请求参数的获取:@RequestParam
path(用于restful接口)–>请求参数的获取:@PathVariable
body(不常用)
form(不常用)- name:参数名
- dataType:参数类型 required:参数是否必须传 value:参数的意思
- defaultValue:参数的默认值
-
@ApiResponses:用于表示一组响应
-
@ApiResponse:用在@ApiResponses中,一般用于表达一个错误的响应信息
code:数字,例如400
message:信息,例如"请求参数没填好"
response:抛出异常的类
- @ApiModel:描述一个Model的信息(这种一般用在post创建的时候,使用@RequestBody这样的场景,请求参数无法使用@ApiImplicitParam注解进行描述的时候)
- @ApiModelProperty:描述一个model的属性
7 Swagger添加全局变量参数(全局token需求)
修改SwaggerConfig类
- 方法1:每条API单独添加
- 方法2:所有API统一添加
package com.zyu.boot.demo.swagger;
import io.swagger.annotations.ApiOperation;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.ParameterBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.schema.ModelRef;
import springfox.documentation.service.*;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.contexts.SecurityContext;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
import java.util.ArrayList;
import java.util.List;
/**
* swagger配置类
*/
@ConditionalOnProperty(name = "debugSwitch", havingValue = "true")
@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Bean
public Docket DemoRestApi() {
// 添加token方式一,每条API单独添加
ParameterBuilder tokenPar = new ParameterBuilder();
List<Parameter> params = new ArrayList<>();
tokenPar.name("token").description("令牌").modelRef(new ModelRef("string")).parameterType("header")
.required(false).build();
params.add(tokenPar.build());
return new Docket(DocumentationType.SWAGGER_2)
.groupName("Test Api")
.select()
// 扫描指定包中的swagger注解
// .apis(RequestHandlerSelectors.basePackage(""))
/*
* 重要的两个方法: apis():指定要生成文档的接口包基本路径 paths():指定针对哪些请求生成接口文档
* 参考官方资料:http://www.baeldung.com/swagger-2-documentation-for-spring-rest-api
*/
// 扫描所有有注解的api,用这种方式更灵活
.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
// .apis(RequestHandlerSelectors.any())
.paths(PathSelectors.any()).build().apiInfo(apiInfo())
// .securitySchemes(securitySchemes())
// .securityContexts(securityContexts())
.globalOperationParameters(params);
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder().title("SpringBoot Demo RESTful APIs").
description("测试接口").
termsOfServiceUrl("#").
contact(new Contact("zyu", "#", "zyu@zyu.com")).
version("1.0.0").build();
}
// 添加token方式二,所有API统一添加
// private List<ApiKey> securitySchemes() {
// List<ApiKey> apiKeyList = new ArrayList<ApiKey>();
// apiKeyList.add(new ApiKey("Authorization", "token","header"));
// return apiKeyList;
// }
//
// private List<SecurityContext> securityContexts() {
// List<SecurityContext> securityContexts = new ArrayList<>();
// securityContexts.add(
// SecurityContext.builder().securityReferences(defaultAuth())
// .forPaths(PathSelectors.regex("^(?!auth).*$")).build());
// return securityContexts;
// }
//
// private List<SecurityReference> defaultAuth() {
// AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
// AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
// authorizationScopes[0] = authorizationScope;
// List<SecurityReference> securityReferences = new ArrayList<>();
// securityReferences.add(new SecurityReference("Authorization", authorizationScopes));
// return securityReferences;
// }
}
在TestController中新建测试接口
@ApiOperation(value = "测试接口带token请求头", notes = "测试使用swagger请求时,添加token头")
@ApiImplicitParams({
@ApiImplicitParam(name = "name", value = "姓名", required = true, paramType = "query"),})
@GetMapping("/sayHelloWithToken")
public String sayHelloWithToken(@Param("name") String name, @RequestHeader("token") String token) {
return "hello," + name + ",token:" + token;
}
- 新建接口中添加了token
- 原来第一个接口上也加了token
8 结束语
今天swagger的集成就先到这里了,ResponseBody的情况可以自己再试试!!!这里就不再赘述了
同时也别忘了使用git提交更改的代码哦!!!