在工作中,我们在开发一些API时,在完成后通常是需要提供一份相应的接口文档的,所以我们在开发之余还需要耗费一定的时间和精力来完成接口文档的编号,并且在编写接口文档中,随着需求的变更和项目的优化、推进,接口的细节在不断地演变,接口描述文档也需要同步修订,就十分的麻烦,所以我们可以采用自动生成文档模式:swagger2、RAP等。
这里我们主要来介绍一个Swagger2的基本用法,Swagger2可以随项目自动生成强大restful API文档,减少工作量,API文档与代码整合在一起,便于同步更新API说明,并且提供了页面测试功能来调试每个restful API。
首先在使用Swagger2时,我们首先要做的就是引入相关的依赖,如下:
<dependency>
<groupId>io.springfoxgroupId>
<artifactId>springfox-swagger-uiartifactId>
<version>2.9.2version>
dependency>
<dependency>
<groupId>io.springfoxgroupId>
<artifactId>springfox-swagger2artifactId>
<version>2.9.2version>
dependency>
然后我们需要添加一个Swagger2的配置类,如下:
@Configuration
@EnableSwagger2
public class Swagger2Config {
//api接口包扫描路径
public static final String SWAGGER_SCAN_BASE_PACKAGE = "com.kimi";
//api接口文档版本信息
public static final String VERSION = "1.0.0";
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
//为指定包下Controller生成API文档
.apis(RequestHandlerSelectors.basePackage(SWAGGER_SCAN_BASE_PACKAGE))
.paths(PathSelectors.any())
.build();
}
//创建api的基本信息
private ApiInfo apiInfo() {
Contact contact = new Contact("Kimi", "www.kimi0107.com", "[email protected]");
return new ApiInfoBuilder()
//设置文档的标题
.title("集成Swagger2构建API文档")
//设置文档的描述
.description("SpringBoot集成Swagger2构建restful API文档")
//设置文档的License信息
.termsOfServiceUrl("http://www.kimi0107.com/")
//设置文档的联系信息
.contact(contact)
//设置文档的版本信息
.version(VERSION)
.build();
}
}
如上代码所示,通过@Configuration
注解,让Spring加载该配置类。再通过@EnableSwagger2
注解来启用Swagger2。成员方法 createRestApi 函数创建 Docket 的Bean之后,apiInfo() 用来创建该 Api 的基本信息(这些基本信息会展现在文档页面中)。
select() 函数返回一个 ApiSelectorBuilder实例用来控制哪些接口暴露给 Swagger 来展现,本例采用指定扫描的包路径来定义,Swagger 会扫描该包下所有 Controller 定义的 API,并产生文档内容(除了被@ApiIgnore
指定的请求)。
当然我们处理指定扫描的包路径来定义生成接口文档的接口,还可以通过其他的方式,其常用方式有如下几种
在完成了上述配置后,其实已经可以产生文档内容,但是这样的文档主要针对请求本身,而描述主要来源于函数等命名产生,对用户并不友好,启动项目,访问http://localhost:8080/swagger-ui.html,界面如下:
从上述截图看出,该界面其实已经非常强大了,我们还可以直接在其中进行测试,但是在实际使用中,我们还可以自己来增加一些说明来丰富文档内容,比较比较常见的@ApiOperation
和@ApiImplicitParam
两个注解,如下:
另外如果方法中含有多个参数,我们可以使用@ApiImplicitParams
来代替@ApiImplicitParam
,其用法也非常简单,就是一个可以含有多个@ApiImplicitParam
数组的参数
但是有时我们经常会使用到实体类来进行传参,这里我们就需要用到 @ApiModel
和 @ApiModelProperty
,在使用到的实体类上进行注解说明,如下:
下面还有一些我们在工作中,经常使用到的注解,如下:
@Api(tags=“说明该类的作用”, value=“该参数没什么意义,一般不进行配置”)
修饰整个类,放在请求的类上,与@Controller并列,说明类的作用,如用户模块API,订单模块API等。
@ApiOperation(value=“说明方法的作用”,notes=“方法的备注说明”)
@ApiImplicitParam:
对单个参数的说明
@ApiImplicitParams:
用在请求的方法上,包含一组参数说明
@ApiImplicitParams({
@ApiImplicitParam(name=“id”,value=“用户ID”,required=true,paramType=“form”),
@ApiImplicitParam(name=“name”,value=“用户名称”,required=true,paramType=“form”),
@ApiImplicitParam(name=“age”,value=“用户年龄”,required=true,paramType=“form”,dataType=“Integer”)
})
name:参数名
value:参数的汉字说明、解释
required:参数是否必须传
paramType:参数放在哪个地方
header --> 请求参数的获取:@RequestHeader
query --> 请求参数的获取:@RequestParam
path(用于restful接口)–> 请求参数的获取:@PathVariable
body(请求体)–> @RequestBody User user
form(普通表单提交)
dataType:参数类型,默认String,其它值dataType=“int”
defaultValue:参数的默认值
@ApiResponses:
方法返回对象的说明
@ApiResponse:
每个参数的说明
@ApiResponses({
@ApiResponse(code = 400, message = “请求参数没填好”),
@ApiResponse(code = 404, message = “请求路径找不到”)
})
code:数字,例如400
message:信息,例如"请求参数没填好"
response:抛出异常的类
使用注解忽略该API,不会参与文档生成
发生错误返回的信息
用对象接收参数时,描述对象的一个字段
在集成了Swagger2构建API文档,可能我们只需要在测试环境中进行使用,而在生成环境中是要求关闭的,这里我们可以在SpringBoot的.properties文件或.yml文件中,进行相关的配置,如下:
swagger.enable=true
swagger:
enable: true
另外如果我们在项目中集成了Spring Security,或者集成了Shiro等权限控制之类的,在不做额外配置的情况下,Swagger2文档会被拦截。解决方法是在相关的配置类中添加白名单即可:
如在Security 的配置类中重写configure方法即可:
@Override
public void configure (WebSecurity web) throws Exception {
web.ignoring()
.antMatchers("/swagger-ui.html")
.antMatchers("/v2/**")
.antMatchers("/swagger-resources/**");
}
或如在Shiro的配置类中进行相关配置,如下:
//swagger2免拦截
filterChainDefinitionMap.put("/swagger-ui.html**", "anon");
filterChainDefinitionMap.put("/v2/api-docs", "anon");
filterChainDefinitionMap.put("/swagger-resources/**", "anon");
filterChainDefinitionMap.put("/webjars/**", "anon");
继承了WebMvcConfigurationSupport ,重写了addResourceHandlers方法
/**
* 配置swagger2的静态资源路径
*/
@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
// 解决静态资源无法访问
registry.addResourceHandler("/**")
.addResourceLocations("classpath:/static/");
// 解决swagger无法访问
registry.addResourceHandler("/swagger-ui.html")
.addResourceLocations("classpath:/META-INF/resources/");
// 解决swagger的js文件无法访问
registry.addResourceHandler("/webjars/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/");
}