一、Swagger2 简介
由于Spring Boot能够快速开发、便捷部署等特性,相信有很大一部分Spring Boot的用户会用来构建RESTful API。而我们构建RESTful API的目的通常都是由于多终端的原因,这些终端会共用很多底层业务逻辑,因此我们会抽象出这样一层来同时服务于多个移动端或者Web前端。
这样一来,我们的RESTful API就有可能要面对多个开发人员或多个开发团队:IOS开发、Android开发或是Web开发等。为了减少与其他团队平时开发期间的频繁沟通成本,传统做法我们会创建一份RESTful API文档来记录所有接口细节,然而这样的做法有以下几个问题:
由于接口众多,并且细节复杂(需要考虑不同的HTTP请求类型、HTTP头部信息、HTTP请求内容等),高质量地创建这份文档本身就是件非常吃力的事,下游的抱怨声不绝于耳。
随着时间推移,不断修改接口实现的时候都必须同步修改接口文档,而文档与代码又处于两个不同的媒介,除非有严格的管理机制,不然很容易导致不一致现象。
为了解决上面这样的问题,本文将介绍RESTful API的重磅好伙伴Swagger2,它可以轻松的整合到Spring Boot中,并与Spring MVC程序配合组织出强大RESTful API文档。它既可以减少我们创建文档的工作量,同时说明内容又整合入实现代码中,让维护文档和修改代码整合为一体,可以让我们在修改代码逻辑的同时方便的修改文档说明。另外Swagger2也提供了强大的页面测试功能来调试每个RESTful API。具体效果如下图所示:
二、Maven依赖
<!--swagger-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
<exclusions>
<exclusion>
<groupId>io.swagger</groupId>
<artifactId>swagger-annotations</artifactId>
</exclusion>
<exclusion>
<groupId>io.swagger</groupId>
<artifactId>swagger-models</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-annotations</artifactId>
<version>1.5.21</version>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-models</artifactId>
<version>1.5.21</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
<!--swagger插件-->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>swagger-bootstrap-ui</artifactId>
<version>1.9.3</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-bean-validators</artifactId>
<version>2.9.2</version>
</dependency>
三、配置文件
1. 配置文件
@Configuration
@EnableSwagger2
@EnableSwaggerBootstrapUI
@Import(BeanValidatorPluginsConfiguration.class)
public class Swagger2Config {
@Bean
public Docket controllerApi() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.groupName("默认接口")
.select()
.apis(RequestHandlerSelectors.basePackage("com.xxxx.admin.modules.system.controller.admin"))
.paths(PathSelectors.any())
.build();
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("XXXXXXXXX")
.description("描述:XXXXXXX!")
.termsOfServiceUrl("http://www.xtsz.com/")
.contact(new Contact("marquis","http://www.XXXXXX.com/","XXXXXXX@qq.com"))
.version("版本号:1.0.0")
.build();
}
/**
* 安全认证
* @return
*/
List<SecurityReference> defaultAuth() {
AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
authorizationScopes[0] = authorizationScope;
return Lists.newArrayList(new SecurityReference("BearerToken", authorizationScopes));
}
List<SecurityReference> defaultAuth1() {
AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
authorizationScopes[0] = authorizationScope;
return Lists.newArrayList(new SecurityReference("BearerToken1", authorizationScopes));
}
}
2. 权限设置
// swagger-ui
.antMatchers("/swagger-ui.html").permitAll()
.antMatchers("/doc.html").permitAll()
.antMatchers("/swagger-resources/**").permitAll()
.antMatchers("/images/**").permitAll()
.antMatchers("/webjars/**").permitAll()
.antMatchers("/v2/api-docs").permitAll()
.antMatchers("/configuration/ui").permitAll()
.antMatchers("/configuration/security").permitAll()
// swagger-ui
3. 浏览访问:
http://localhost:8000/doc.html
4. 全局设置
四、相关注解
swagger通过注解表明该接口会生成文档,包括接口名、请求方法、参数、返回信息的等等。
@Api:修饰整个类,描述Controller的作用
@ApiOperation:描述一个类的一个方法,或者说一个接口
@ApiParam:单个参数描述
@ApiModel:用对象来接收参数
@ApiProperty:用对象接收参数时,描述对象的一个字段
@ApiResponse:HTTP响应其中1个描述
@ApiResponses:HTTP响应整体描述
@ApiIgnore:使用该注解忽略这个API
@ApiError :发生错误返回的信息
@ApiParamImplicit:一个请求参数
@ApiParamsImplicits: 多个请求参数
五、注解使用
- 实体类注解
@ApiModelProperty()用于方法,字段; 表示对model属性的说明或者数据操作更改
value–字段说明
name–重写属性名字
dataType–重写属性类型
required–是否必填
example–举例说明
hidden–隐藏
@Data
@ApiModel
public class LoginUser {
@NotNull(message = "账号不能为空")
@ApiModelProperty(value = "账号", required = true)
private String username;
@NotNull(message = "密码不能为空")
@ApiModelProperty(value = "登录密码", required = true)
private String password;
@ApiModelProperty(value="记住密码 0不记 1记住",required = true,example="0")
private Integer rememberMe;
}
- 控制器类注解
@Api:用在请求的类上,表示对类的说明
tags="说明该类的作用,可以在UI界面上看到的注解"
value="该参数没什么意义,在UI界面上也看到,所以不需要配置"
@Api(tags = {"1、用户登录"})
public class AuthController {
}
- 控制器方法注解
@ApiOperation() 用于方法;表示一个http请求的操作
value用于方法描述
notes用于提示内容
tags可以重新分组(视情况而用)
@PostMapping("/login")
@ApiOperation(value = "1、用户登录", notes = "使用账号密码登录", httpMethod = "POST")
public String login(@RequestBody LoginUser loginUser){
}
- @ApiImplicitParam
在 Rest 接口上单独使用
@ApiImplicitParam 在 Rest 接口上单独使用的时候,表示单个请求参数
在 Rest 接口上和 @ApiImplicitParams 组合使用
@ApiImplicitParam 在 Rest 接口上和 @ApiImplicitParams 组合时候,表示多个请求参数
属性
属性名称 | 数据类型 | 默认值 | 说明 |
---|---|---|---|
name | String | “” | 参数名称(实体类字段名称) |
value | String | “” | 参数简要说明 |
defaultValue | String | “” | 描述参数的默认值 |
allowableValues | String | “” | 限制此参数接收的值,可使用的值或值得范围 |
required | boolean | false | 指定是否为必填参数,false:非必传参数; true:必传参数 |
access | String | “” | 参数过滤,参考: io.swagger.core.filter.SwaggerSpecFilte |
allowMultiple | boolean | false | 指定参数是否可以通过多次出现来接收多个值 |
dataType | String | “” | 参数的数据类型,可以使类名或原始数据类型 |
dataTypeClass | Class<?> | Void.class | 参数的类,如果提供则覆盖 dataType |
paramType | String | “” | 参数的参数类型,有效值为 path, query, body, header, form |
example | String | “” | 非请求体(body)参数的单个请求示例 |
examples | Example | @Example(value = @ExampleProperty(mediaType = “”, value = “”)) | 参数示例,仅适用于 BodyParameters(请求体类型的) |
type | String | “” | 添加覆盖检测到的类型的功能 |
format | String | “” | 添加提供自定义格式的功能 |
allowEmptyValue | boolean | false | 添加将 format 设置为空的功能 |
readOnly | boolean | false | 添加被指定为只读的能力 |
collectionFormat | String | “” | 添加使用 array 类型 collectionFormat 的功能 |
paramType属性:
header : 请求参数的获取:@RequestHeader
query : 请求参数的获取:@RequestParam
path : 请求参数的获取:@PathVariable
body : 请求参数的获取:@RequestBody
form : 不常用
- @ApiImplicitParams
在 Rest 接口方法上使用来指定请求参数
属性
属性名称 | 数据类型 | 默认值 | 说明 |
---|---|---|---|
value | ApiImplicitParam[] | API 可用的 | 参数列表 |
@GetMapping("/getUserName")
@ApiOperation(value = "1、获取账号名称", notes = "使用账号密码登录", httpMethod = "GET")
@ApiImplicitParams({
@ApiImplicitParam(name = "username", value = "账号名称", dataType = "String"),
@ApiImplicitParam(name = "password", value = "密码", dataType = "String")})
public String getUserName(String username, String password, HttpServletRequest request) {
String str = "本地端口:" + request.getLocalPort() + "远程端口:" + request.getRemotePort() + "服务端口:" + request.getServerPort();
return "用户名为:" + username + "密码:" + password + "---->" + str;
}
六、权限控制
生产环境不可调用查看。
在Swagger2的配置类上添加注解。
@Profile({"dev", "test"})