Spring Boot(八)集成swagger
之前一直维护wiki,不是用测试用例就是用postman工具,偶然的机会相遇了swagger,感觉很是试用。所以决定将其配置流程乃至中间遇到的坑记录下来。
一、何为swagger?
Swagger 是一个规范和完整的框架,用于生成、描述、调用和可视化 RESTful 风格的 Web 服务。总体目标是使客户端和文件系统作为服务器以同样的速度来更新。文件的方法,参数和模型紧密集成到服务器端的代码,允许API来始终保持同步。Swagger 让部署管理和使用功能强大的API从未如此简单。
二、配置流程
maven依赖
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.8.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.8.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.6</version>
</dependency>
swagger 配置类
@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.basePackage("com.openplatform.api.controller"))
.paths(PathSelectors.any())
.build()
.globalOperationParameters(pars)
.apiInfo(apiInfo());
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("街云相关接口测试")
.description("如下链接是直接跳转到wiki的,方便快捷")
.contact(new Contact("wiki address", "http://192.168.31.215:9999/dokuwiki/doku.php?id=start", ""))
.license("")
.licenseUrl("")
.version("1.0.0")
.build();
}
}
三、遇到的坑
1、因为swagger是页面化的,所以最基本的则是集成其自己的html页面以及其样式包
页面错误展示:{“code”:404,“data”:{},“msg”:“Not Found”,“status”:false}
代码错误:
未集成html的错误
2018-12-04 17:23:06.444|WARN ||o.s.w.s.PageNotFound|No mapping found for HTTP request with URI [/swagger-ui.html] in DispatcherServlet with name 'dispatcherServlet'
2018-12-04 17:23:06.500|ERROR||c.o.a.w.ErrorInfoBuilder|api error /swagger-ui.html
headers={Accept=text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8, Cache-Control=max-age=0, Upgrade-Insecure-Requests=1, User-Agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36, Connection=keep-alive, If-Modified-Since=Mon, 15 Jan 2018 08:59:31 GMT, Host=127.0.0.1:8181, Accept-Language=zh-CN,zh;q=0.9,en;q=0.8, Accept-Encoding=gzip, deflate, br}
java.lang.Exception: Not Found
at com.openplatform.api.web.ErrorInfoBuilder.getError(ErrorInfoBuilder.java:133)
未集成其样式导致的
2018-12-04 17:16:35.081|WARN ||o.s.w.s.PageNotFound|No mapping found for HTTP request with URI [/webjars/springfox-swagger-ui/springfox.js] in DispatcherServlet with name 'dispatcherServlet'
2018-12-04 17:16:35.082|ERROR||c.o.a.w.ErrorInfoBuilder|api error /webjars/springfox-swagger-ui/springfox.js
headers={Accept=*/*, Connection=keep-alive, User-Agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36, Referer=http://127.0.0.1:8181/swagger-ui.html, Host=127.0.0.1:8181, Accept-Language=zh-CN,zh;q=0.9,en;q=0.8, Accept-Encoding=gzip, deflate, br}
java.lang.Exception: Not Found
解决办法:
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
//swagger静态页面和样式加载
registry.addResourceHandler("swagger-ui.html")
.addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/");
}
2、版本冲突
Caused by: java.lang.NoSuchMethodError: com.google.common.collect.FluentIterable.concat(Ljava/lang/Iterable;Ljava/lang/Iterable;)Lcom/google/common/collect/FluentIterable;
at springfox.documentation.schema.DefaultModelDependencyProvider.dependentModels(DefaultModelDependencyProvider.java:79)
报如上错误,则肯定是版本不兼容,简单的办法则是通过看相互依赖找到问题,或者直接修改为统一版本,问题则迎刃而解。
注:swagger 2.7.0确实有很多问题,大家可以略过这个版本。
四 TOKEN机制优化
对于Restful风格的接口,身份信息都是放在请求头中,通过拦截器来读取Header中的Token信息进行身份验证,但是我们在Swagger中怎么设置请求头参数,我们需要在每一个方法的中都加一个Header参数吗?当然不是。Swagger中的ParameterBuilder可以为我们所有的接口文档加上Token参数。想加几个验证参数限制都可以。
修改swaggerConfig的方法,添加token参数:
@Bean
public Docket createRestApi() {
//token和APPID参数传入配置
List<Parameter> pars = new ArrayList<>();
ParameterBuilder tokenPar = new ParameterBuilder();
//参数名称
tokenPar.name("Authorization")
//参数默认值
.defaultValue("")
//参数描述
.description("令牌")
//类型
.modelRef(new ModelRef("string")).parameterType("header").required(false).build();
ParameterBuilder appIdPar = new ParameterBuilder();
appIdPar.name("x-app-id")
.defaultValue("10001")
.description("appID")
.modelRef(new ModelRef("string")).parameterType("header").required(false).build();
pars.add(tokenPar.build());
pars.add(appIdPar.build());
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.basePackage("com.openplatform.api.controller"))
.paths(PathSelectors.any())
.build()
.globalOperationParameters(pars)
.apiInfo(apiInfo());
}
五 swagger页面样式
样式的展示和swagger的版本有直接关系,我的版本是2.8.0,所以如下的页面样式是2.8.0版本的效果。
token机制部分截图:
默认都是不必传的,是否需要传入参数是通过项目拦截判定的。
以上几点就是腿swagger配置的基本流程以及一点心得,swagger的出现很是方便了我们测试环境的使用,但是对于生产环境而言,确是一种危险。所以下篇则主要介绍生产环境如何禁用swagger。