目录
格式美化 #%E6%A0%BC%E5%BC%8F%E7%BE%8E%E5%8C%96%C2%A0
前言
这是一个突破性的变更
有关此项目的更多信息,请访问API Documentation & Design Tools for Teams | Swagger
什么是Swagger
Swagger 是最流行的 API 开发工具
Swagger Codegen: 通过Codegen 可以将描述文件生成html格式和cwiki形式的接口文档,同时也能生成多钟语言的服务端和客户端的代码。支持通过jar包,docker,node等方式在本地化执行生成。也可以在后面的Swagger Editor中在线生成。
Swagger UI:提供了一个可视化的UI页面展示描述文件。接口的调用方、测试、项目经理等都可以在该页面中对相关接口进行查阅和做一些简单的接口请求。该项目支持在线导入描述文件和本地部署UI项目。
Swagger Editor: 类似于markendown编辑器的编辑Swagger描述文件的编辑器,该编辑支持实时预览描述文件的更新效果。也提供了在线编辑器和本地部署编辑器两种方式。
Swagger Inspector: 感觉和postman差不多,是一个可以对接口进行测试的在线版的postman。比在Swagger UI里面做接口请求,会返回更多的信息,也会保存你请求的实际请求参数等数据。
Swagger Hub:集成了上面所有项目的各个功能,你可以以项目和版本为单位,将你的描述文件上传到Swagger Hub中。在Swagger Hub中可以完成上面项目的所有工作,需要注册账号,分免费版和收费版。
PS:
Springfox Swagger: Spring 基于swagger规范,可以将基于SpringMVC和Spring Boot项目的项目代码,自动生成JSON格式的描述文件。本身不是属于Swagger官网提供的,在这里列出来做个说明,方便后面作一个使用的展开。
有用的链接
项目集成
本文将通过几个简单步骤教大家如何集成Swagger3
共三个步骤,步骤如下:
1、添加依赖
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-boot-starter</artifactId>
<version>3.0.0</version>
</dependency>
2、启动类配置
@EnableOpenApi
@SpringBootApplication
public class SwaggerApplication {
public static void main(String[] args) {
SpringApplication.run(SwaggerApplication.class, args);
}
}
@EnableOpenApi
这个注解文档解释如下:
Indicates that Swagger support should be enabled.
This should be applied to a Spring java config and should have an accompanying '@Configuration' annotation.
Loads all required beans defined in @see SpringSwaggerConfig
只有在配置类标注了@EnableOpenApi
这个注解才会生成Swagger文档
3、启动项目
访问:http://localhost:8080/swagger-ui/index.html
一个简单的Swagger后台接口文档,至此就搭建完成了。
可以看到,上面那个界面中,默认显示了一个basic-error-controller
接口分组,但是我们并没有写;
通过在项目中查找我们发现,SpringBoot内部确实有这样一个控制器类,如下所示
说明Swagger默认的配置,会自动把@Controller控制器类添加到接口文档中
分组
分组其实很简单,Swagger
向IOC
中注入一个Docket
即为一个组的文档,其中有个groupName()
方法指定分组的名称。
因此只需要注入多个Docket
指定不同的组名即可,当然,这些文档的标题、描述、扫描的路径都是可以不同定制的。
如下配置两个Docket
,分为前台和后台,配置类如下:
第一步:添加Swagger3自定义配置类(可选)
下面我们就自己配置一下,如下所示:
@EnableOpenApi
@Configuration
@EnableConfigurationProperties(value = {SwaggerProperties.class})
public class SwaggerConfig {
/**
* 配置属性
*/
@Autowired
private SwaggerProperties properties;
@Bean
public Docket frontApi() {
return new Docket(DocumentationType.OAS_30)
//是否开启,根据环境配置
.enable(properties.getFront().getEnable())
.groupName(properties.getFront().getGroupName())
.apiInfo(frontApiInfo())
.select()
//指定扫描的包
.apis(RequestHandlerSelectors.basePackage(properties.getFront().getBasePackage()))
.paths(PathSelectors.any())
.build();
}
/**
* 前台API信息
*/
private ApiInfo frontApiInfo() {
return new ApiInfoBuilder()
.title(properties.getFront().getTitle())
.description(properties.getFront().getDescription())
.version(properties.getFront().getVersion())
.contact( //添加开发者的一些信息
new Contact(properties.getFront().getContactName(), properties.getFront().getContactUrl(),
properties.getFront().getContactEmail()))
.build();
}
/**
* 后台API
*/
@Bean
public Docket backApi() {
return new Docket(DocumentationType.OAS_30)
//是否开启,根据环境配置
.enable(properties.getBack().getEnable())
.groupName("后台管理")
.apiInfo(backApiInfo())
.select()
.apis(RequestHandlerSelectors.basePackage(properties.getBack().getBasePackage()))
.paths(PathSelectors.any())
.build();
}
/**
* 后台API信息
*/
private ApiInfo backApiInfo() {
return new ApiInfoBuilder()
.title(properties.getBack().getTitle())
.description(properties.getBack().getDescription())
.version(properties.getBack().getVersion())
.contact( //添加开发者的一些信息
new Contact(properties.getBack().getContactName(), properties.getBack().getContactUrl(),
properties.getBack().getContactEmail()))
.build();
}
}
第二步:属性文件配置
属性配置文件SwaggerProperties
如下,分为前台和后台两个不同属性的配置:
/**
* swagger的属性配置类
*/
@ConfigurationProperties(prefix = "spring.swagger")
@Data
public class SwaggerProperties {
/**
* 前台接口配置
*/
private SwaggerEntity front;
/**
* 后台接口配置
*/
private SwaggerEntity back;
@Data
public static class SwaggerEntity {
private String groupName;
private String basePackage;
private String title;
private String description;
private String contactName;
private String contactEmail;
private String contactUrl;
private String version;
private Boolean enable;
}
}
授权
如何添加授权信息?
现在项目API肯定都需要权限认证,否则不能访问,比如请求携带一个TOKEN
。
在Swagger中也是可以配置认证信息,这样在每次请求将会默认携带上。
在Docket
中有如下两个方法指定授权信息,分别是securitySchemes()
和securityContexts()
。在配置类中的配置如下,在构建Docket的时候设置进去即可:
@Bean
public Docket frontApi() {
RequestParameter parameter = new RequestParameterBuilder()
.name("platform")
.description("请求头")
.in(ParameterType.HEADER)
.required(true)
.build();
List<RequestParameter> parameters = Collections.singletonList(parameter);
return new Docket(DocumentationType.OAS_30)
//是否开启,根据环境配置
.enable(properties.getFront().getEnable())
.groupName(properties.getFront().getGroupName())
.apiInfo(frontApiInfo())
.select()
//指定扫描的包
.apis(RequestHandlerSelectors.basePackage(properties.getFront().getBasePackage()))
.paths(PathSelectors.any())
.build()
.securitySchemes(securitySchemes())
.securityContexts(securityContexts());
}
/**
* 设置授权信息
*/
private List<SecurityScheme> securitySchemes() {
ApiKey apiKey = new ApiKey("BASE_TOKEN", "token", In.HEADER.toValue());
return Collections.singletonList(apiKey);
}
/**
* 授权信息全局应用
*/
private List<SecurityContext> securityContexts() {
return Collections.singletonList(
SecurityContext.builder()
.securityReferences(Collections.singletonList(new SecurityReference("BASE_TOKEN", new AuthorizationScope[]{new AuthorizationScope("global", "")})))
.build()
);
}
复制代码
以上配置成功后,在Swagger文档的页面中将会有Authorize
按钮,只需要将请求头添加进去即可。如下图:
如何携带公共的请求参数?
不同的架构可能发请求的时候除了携带TOKEN
,还会携带不同的参数,比如请求的平台,版本等等,这些每个请求都要携带的参数称之为公共参数。
那么如何在Swagger
中定义公共的参数呢?比如在请求头中携带。
在Docket
中的方法globalRequestParameters()
可以设置公共的请求参数,接收的参数是一个List<RequestParameter>
,因此只需要构建一个RequestParameter
集合即可,如下:
@Bean
public Docket frontApi() {
//构建一个公共请求参数platform,放在在header
RequestParameter parameter = new RequestParameterBuilder()
//参数名称
.name("platform")
//描述
.description("请求的平台")
//放在header中
.in(ParameterType.HEADER)
//是否必传
.required(true)
.build();
//构建一个请求参数集合
List<RequestParameter> parameters = Collections.singletonList(parameter);
return new Docket(DocumentationType.OAS_30)
.....
.build()
.globalRequestParameters(parameters);
}
格式美化
第一步:添加bootstrap-ui支持
<!--swagger-bootstrap-ui-->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>swagger-bootstrap-ui</artifactId>
<version>1.9.6</version>
</dependency>
第二步:启动项目
访问:http://localhost:8080/doc.html (可选)
注解说明
@Api:用在请求的类上,表示对类的说明
tags="说明该类的作用,可以在UI界面上看到的注解"
value="该参数没什么意义,在UI界面上也看到,所以不需要配置"
@ApiOperation:用在请求的方法上,说明方法的用途、作用
value="说明方法的用途、作用"
notes="方法的备注说明"
@ApiImplicitParams:用在请求的方法上,表示一组参数说明
@ApiImplicitParam:用在@ApiImplicitParams注解中,指定一个请求参数的各个方面
name:参数名
value:参数的汉字说明、解释
required:参数是否必须传
paramType:参数放在哪个地方
· header --> 请求参数的获取:@RequestHeader
· query --> 请求参数的获取:@RequestParam
· path(用于restful接口)--> 请求参数的获取:@PathVariable
· div(不常用)
· form(不常用)
dataType:参数类型,默认String,其它值dataType="Integer"
defaultValue:参数的默认值
@ApiResponses:用在请求的方法上,表示一组响应
@ApiResponse:用在@ApiResponses中,一般用于表达一个错误的响应信息
code:数字,例如400
message:信息,例如"请求参数没填好"
response:抛出异常的类
@ApiModel:用于响应类上,表示一个返回响应数据的信息
(这种一般用在post创建的时候,使用@RequestBody这样的场景,
请求参数无法使用@ApiImplicitParam注解进行描述的时候)
@ApiModelProperty:用在POJO属性上,描述响应类的属性说明
@ApiResponse:用在@ApiResponses中,一般用于表达一个错误的响应信息
code:状态码数字,例如400
message:信息,例如"请求参数没填好"
response:抛出异常的类
@ApiIgnore:使用该注解忽略这个某个API或者参数;
示例代码
#####Controller代码
@Override
@ApiOperation(value = "post请求调用示例", notes = "invokePost说明", httpMethod = "POST")
public FFResponseModel<DemoOutputDto> invokePost(@ApiParam(name="传入对象",value="传入json格式",required=true) @RequestBody @Valid DemoDto input) {
log.info("/testPost is called. input=" + input.toString());
return new FFResponseModel(Errcode.SUCCESS_CODE, Errcode.SUCCESS_MSG);
}
#####接口请求入参对象
@Data
@ApiModel(value="演示类",description="请求参数类" )
public class DemoDto implements Serializable {
private static final long serialVersionUID = 1L;
@NotNull
@ApiModelProperty(value = "defaultStr",example="mockStrValue")
private String strDemo;
@NotNull
@ApiModelProperty(example="1234343523",required = true)
private Long longNum;
@NotNull
@ApiModelProperty(example="111111.111")
private Double doubleNum;
@NotNull
@ApiModelProperty(example="2018-12-04T13:46:56.711Z")
private Date date;
}
#####接口请求出参公共类
@ApiModel(value="基础返回类",description="基础返回类")
public class FFResponseModel<T> implements Serializable {
private static final long serialVersionUID = -2215304260629038881L;
// 状态码
@ApiModelProperty(example="成功")
private String code;
// 业务提示语
@ApiModelProperty(example="000000")
private String msg;
// 数据对象
private T data;
...
}
#####接口请求出参实际数据对象
@Data
public class DemoOutputDto {
private String res;
@NotNull
@ApiModelProperty(value = "defaultOutputStr",example="mockOutputStrValue")
private String outputStrDemo;
@NotNull
@ApiModelProperty(example="6666666",required = true)
private Long outputLongNum;
@NotNull
@ApiModelProperty(example="88888.888")
private Double outputDoubleNum;
@NotNull
@ApiModelProperty(example="2018-12-12T11:11:11.111Z")
private Date outputDate;
}