一、前言
记录一下遇到的在SpringBoot项目中引用Swagger配置时启动报错,导致Swagger无法访问,但是项目可以启动并能访问后台接口。
二、报错信息
1、后台错误信息:
2022-01-24 13:42:20.638 ERROR 18508 --- [ main] d.s.w.p.DocumentationPluginsBootstrapper : Unable to scan documentation context default
java.lang.NullPointerException: null
at springfox.documentation.schema.Example.equals(Example.java:131)
at java.util.Objects.equals(Objects.java:59)
at springfox.documentation.service.RequestParameter.equals(RequestParameter.java:132)
at java.util.HashMap.putVal(HashMap.java:635)
at java.util.HashMap.put(HashMap.java:612)
at java.util.HashSet.add(HashSet.java:220)
at java.util.stream.ReduceOps$3ReducingSink.accept(ReduceOps.java:169)
at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
at java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:175)
at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1382)
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499)
at springfox.documentation.spring.web.readers.operation.OperationParameterReader.apply(OperationParameterReader.java:93)
at springfox.documentation.spring.web.plugins.DocumentationPluginsManager.operation(DocumentationPluginsManager.java:144)
at springfox.documentation.spring.web.readers.operation.ApiOperationReader.read(ApiOperationReader.java:72)
at springfox.documentation.spring.web.scanners.CachingOperationReader.lambda$new$0(CachingOperationReader.java:43)
at java.util.HashMap.computeIfAbsent(HashMap.java:1127)
at springfox.documentation.spring.web.scanners.CachingOperationReader.read(CachingOperationReader.java:48)
at springfox.documentation.spring.web.scanners.ApiDescriptionReader.read(ApiDescriptionReader.java:72)
at springfox.documentation.spring.web.scanners.ApiListingScanner.scan(ApiListingScanner.java:169)
at springfox.documentation.spring.web.scanners.ApiDocumentationScanner.scan(ApiDocumentationScanner.java:67)
at springfox.documentation.spring.web.plugins.AbstractDocumentationPluginsBootstrapper.scanDocumentation(AbstractDocumentationPluginsBootstrapper.java:96)
at springfox.documentation.spring.web.plugins.AbstractDocumentationPluginsBootstrapper.bootstrapDocumentationPlugins(AbstractDocumentationPluginsBootstrapper.java:82)
at springfox.documentation.spring.web.plugins.DocumentationPluginsBootstrapper.start(DocumentationPluginsBootstrapper.java:100)
at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:182)
at org.springframework.context.support.DefaultLifecycleProcessor.access$200(DefaultLifecycleProcessor.java:53)
at org.springframework.context.support.DefaultLifecycleProcessor$LifecycleGroup.start(DefaultLifecycleProcessor.java:360)
at org.springframework.context.support.DefaultLifecycleProcessor.startBeans(DefaultLifecycleProcessor.java:158)
at org.springframework.context.support.DefaultLifecycleProcessor.onRefresh(DefaultLifecycleProcessor.java:122)
at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:895)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:554)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:143)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:758)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:750)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:315)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1237)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226)
2、Swagger错误信息:
Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.
Mon Jan 24 12:00:18 CST 2022
There was an unexpected error (type=Not Found, status=404).
三、问题解析以及解决方案
一、由于源码中重写了equals方法,启动时会传入空值检测报错。
1.点击错误信息的第一排进入源码
2.注意到源码中判空并未对String类型判空。
3.解决方案有两种:
- 修改源码。
- 重新在项目中写该类(在com包下新建springfox.documentation.schema目录,在schema包下新建Example类,将源码copy出来粘贴,在toString方法、equals方法和hashCode方法上加@override,并将equals方法上的判断加上对String类型的判空)。
二、由于在实体类中使用的public修饰符。
1.逐个接口排查,发现某个接口定义的参数对象里面的属性,使用了public修饰,并且使用@Data生成了对应的getter、setter方法:
2.调试代码发现,在springfox.documentation.spring.web.readers.parameter.ModelAttributeParameterExpander类中的168行,存在如下代码:
3.跟踪代码可知,swagger在生成接口参数记录对象时,会保留参数对象中存在getter方法的属性,和使用public修饰的属性,如果同时满足这两个条件,则会造成冲突,将实体类中的public改为private即可。
三、由于Controller中多个实体类接收参数中有相同的字段。
1.Controller层中出现两个接收参数类出现相同字段(DocBaseForm和ApprovalRecordForm中)
2.原因是整合Swagger之后,Controller层某个接口接收了两个实体类,类中的名称一样导致的,将两个实体类中相同字段整合在其中一个当中。
四、由于没有引入swagger的依赖包或依赖包版本太低。
1.检查swagger的依赖包是否成功导入或更新jar包。
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
五、总结
以上就是对于Swagger报错的问题总结,码文不易,如果对你有用的话点个赞收藏下吧~