swagger2问题汇总

swagger2问题汇总

  • 环境:swagger 2.7.0,spring-boot 1.5.9

前言

这里是对在使用swagger时碰到的相关问题汇总。

踩坑

Failed to start bean ‘documentationPluginsBootstrapper’; nested exception is java.lang.NullPointerException

swagger的配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@Configuration
@EnableSwagger2
public class Swagger2 {
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(new ApiInfoBuilder()
.title("测试")
.description("测试")
.termsOfServiceUrl("")
.contact("jilingjun")
.version("1.0")
.build())
.select()
.apis(RequestHandlerSelectors.basePackage("com.bsd.recommend.controller"))
.paths(PathSelectors.any())
.build();
}
}

详细错误如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
org.springframework.context.ApplicationContextException: Failed to start bean 'documentationPluginsBootstrapper'; nested exception is java.lang.NullPointerException
at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:176) ~[spring-context-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.springframework.context.support.DefaultLifecycleProcessor.access$200(DefaultLifecycleProcessor.java:51) ~[spring-context-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.springframework.context.support.DefaultLifecycleProcessor$LifecycleGroup.start(DefaultLifecycleProcessor.java:346) ~[spring-context-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.springframework.context.support.DefaultLifecycleProcessor.startBeans(DefaultLifecycleProcessor.java:149) ~[spring-context-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.springframework.context.support.DefaultLifecycleProcessor.onRefresh(DefaultLifecycleProcessor.java:112) ~[spring-context-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:879) ~[spring-context-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.finishRefresh(EmbeddedWebApplicationContext.java:144) ~[spring-boot-1.5.1.RELEASE.jar:1.5.1.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:545) ~[spring-context-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122) ~[spring-boot-1.5.1.RELEASE.jar:1.5.1.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:737) ~[spring-boot-1.5.1.RELEASE.jar:1.5.1.RELEASE]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:370) ~[spring-boot-1.5.1.RELEASE.jar:1.5.1.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:314) ~[spring-boot-1.5.1.RELEASE.jar:1.5.1.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1162) ~[spring-boot-1.5.1.RELEASE.jar:1.5.1.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1151) ~[spring-boot-1.5.1.RELEASE.jar:1.5.1.RELEASE]
at com.bsd.recommend.RecommendApplication.main(RecommendApplication.java:23) ~[classes/:na]
Caused by: java.lang.NullPointerException: null
at springfox.documentation.builders.RequestHandlerSelectors$4.apply(RequestHandlerSelectors.java:97) ~[springfox-core-2.7.0.jar:2.7.0]
at springfox.documentation.builders.RequestHandlerSelectors$4.apply(RequestHandlerSelectors.java:94) ~[springfox-core-2.7.0.jar:2.7.0]
at com.google.common.base.Present.transform(Present.java:79) ~[guava-19.0.jar:na]
at springfox.documentation.builders.RequestHandlerSelectors$5.apply(RequestHandlerSelectors.java:113) ~[springfox-core-2.7.0.jar:2.7.0]
at springfox.documentation.builders.RequestHandlerSelectors$5.apply(RequestHandlerSelectors.java:110) ~[springfox-core-2.7.0.jar:2.7.0]
at com.google.common.base.Predicates$AndPredicate.apply(Predicates.java:374) ~[guava-19.0.jar:na]
at com.google.common.base.Predicates$AndPredicate.apply(Predicates.java:374) ~[guava-19.0.jar:na]
at com.google.common.collect.Iterators$7.computeNext(Iterators.java:675) ~[guava-19.0.jar:na]
at com.google.common.collect.AbstractIterator.tryToComputeNext(AbstractIterator.java:143) ~[guava-19.0.jar:na]
at com.google.common.collect.AbstractIterator.hasNext(AbstractIterator.java:138) ~[guava-19.0.jar:na]
at springfox.documentation.spring.web.scanners.ApiListingReferenceScanner.scan(ApiListingReferenceScanner.java:48) ~[springfox-spring-web-2.7.0.jar:2.7.0]
at springfox.documentation.spring.web.scanners.ApiDocumentationScanner.scan(ApiDocumentationScanner.java:67) ~[springfox-spring-web-2.7.0.jar:2.7.0]
at springfox.documentation.spring.web.plugins.DocumentationPluginsBootstrapper.scanDocumentation(DocumentationPluginsBootstrapper.java:95) ~[springfox-spring-web-2.7.0.jar:2.7.0]
at springfox.documentation.spring.web.plugins.DocumentationPluginsBootstrapper.start(DocumentationPluginsBootstrapper.java:154) ~[springfox-spring-web-2.7.0.jar:2.7.0]
at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:173) ~[spring-context-4.3.6.RELEASE.jar:4.3.6.RELEASE]
... 14 common frames omitted

初步诊断,swagger在做scan操作抛出了空指针异常。现在只能google了,发现这事一个bug,并且在2.8.0之后进行了修复(2.8.0修复的问题在这里:https://github.com/springfox/springfox/issues/2186)。

(可参考:https://github.com/springfox/springfox/issues/1876)

这个问题是发生在对controller做了切面后才会出现,If I use AOP advice on my method within @RestController I face this issue too because Spring creates proxy class to wrap controller’s method call。

解决方案
  • swagger 2.7.0,spring-boot 1.5.1

既然是个bug,就应该有临时解决方案吧。这还真让我找到了,具体解决的源url就找不到了,就直接帖代码了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
@Configuration
@EnableSwagger2
public class Swagger2 extends WebMvcConfigurerAdapter {

@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addRedirectViewController("/documentation/v2/api-docs", "/v2/api-docs?group=restful-api");
registry.addRedirectViewController("/documentation/swagger-resources/configuration/ui", "/swagger-resources/configuration/ui");
registry.addRedirectViewController("/documentation/swagger-resources/configuration/security", "/swagger-resources/configuration/security");
registry.addRedirectViewController("/documentation/swagger-resources", "/swagger-resources");
}

@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.
addResourceHandler("/documentation/swagger-ui.html**").addResourceLocations("classpath:/META-INF/resources/swagger-ui.html");
registry.
addResourceHandler("/documentation/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
}

@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()).select()
.apis(RequestHandlerSelectors.any()).paths(PathSelectors.any())
.build().forCodeGeneration(true);
}

private ApiInfo apiInfo() {
return new ApiInfoBuilder().title("测试")
.description("测试")
.termsOfServiceUrl("").contact("联系我").version("1.0").build();
}
}

参考


坚持原创技术分享,您的支持将鼓励我继续创作!
Fork me on GitHub