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版本的效果。
swagger页面
token机制部分截图:
默认都是不必传的,是否需要传入参数是通过项目拦截判定的。
token

以上几点就是腿swagger配置的基本流程以及一点心得,swagger的出现很是方便了我们测试环境的使用,但是对于生产环境而言,确是一种危险。所以下篇则主要介绍生产环境如何禁用swagger。

posted on 2018-12-06 17:24  huohuoL  阅读(250)  评论(0编辑  收藏  举报

导航