Play Framework Swagger UI 集成错误

Play Framework Swagger UI Integration Error

我正在尝试将 Swagger UI 集成到由 Play Framework 2 提供的其余部分 API。5.x

我做了以下事情:

  1. 在我的 build.sbt
  2. 中包含以下依赖项
  "io.swagger" %% "swagger-play2" % "1.5.3"
  "org.webjars" %% "webjars-play" % "2.5.0-4"
  "org.webjars" % "swagger-ui" % "2.2.0"
  1. 在我的路线中添加了以下内容:
GET         /swagger.json                controllers.ApiHelpController.getResources
GET         /docs/                       controllers.Assets.at(path="/public/swagger-ui",file="index.html")
GET         /docs/*file                  controllers.Assets.at(path="/public/swagger-ui",file)
  1. 然后我尝试访问 swagger.json

这是我得到的错误:

[error] application -

! @77515gnlp - Internal server error, for (GET) [/swagger.json] ->

play.api.http.HttpErrorHandlerExceptions$$anon: Execution exception[[NullPointerException: null]]
    at play.api.http.HttpErrorHandlerExceptions$.throwableToUsefulException(HttpErrorHandler.scala:280)
    at play.api.http.DefaultHttpErrorHandler.onServerError(HttpErrorHandler.scala:206)
    at play.core.server.netty.PlayRequestHandler$$anonfun$$anonfun$apply.applyOrElse(PlayRequestHandler.scala:100)
    at play.core.server.netty.PlayRequestHandler$$anonfun$$anonfun$apply.applyOrElse(PlayRequestHandler.scala:99)
    at scala.concurrent.Future$$anonfun$recoverWith.apply(Future.scala:346)
    at scala.concurrent.Future$$anonfun$recoverWith.apply(Future.scala:345)
    at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:36)
    at play.api.libs.iteratee.Execution$trampoline$.execute(Execution.scala:70)
    at scala.concurrent.impl.CallbackRunnable.executeWithValue(Promise.scala:44)
    at scala.concurrent.impl.Promise$DefaultPromise.tryComplete(Promise.scala:252)
Caused by: java.lang.NullPointerException: null
    at play.modules.swagger.ApiListingCache$$anonfun$listing.apply(ApiListingCache.scala:15)
    at play.modules.swagger.ApiListingCache$$anonfun$listing.apply(ApiListingCache.scala:11)
    at scala.Option.orElse(Option.scala:289)
    at play.modules.swagger.ApiListingCache$.listing(ApiListingCache.scala:11)
    at controllers.SwaggerBaseApiController.getResourceListing(ApiHelpController.scala:128)
    at controllers.ApiHelpController$$anonfun$getResources.apply(ApiHelpController.scala:74)
    at controllers.ApiHelpController$$anonfun$getResources.apply(ApiHelpController.scala:71)
    at play.api.mvc.ActionBuilder$$anonfun$apply.apply(Action.scala:371)
    at play.api.mvc.ActionBuilder$$anonfun$apply.apply(Action.scala:370)
    at play.api.mvc.Action$.invokeBlock(Action.scala:498)

还有什么我应该添加或研究的吗?

您似乎没有在 application.conf:

中启用 swagger 模块
play.modules.enabled += "play.modules.swagger.SwaggerModule"

我建议您参考这个很棒的博客 post 以获得与 play 框架的正确 swagger 集成:Medium article

祝你好运:)

在进一步查看您的项目后,我明白了您面临的问题是什么。基本上,Play Swagger 模块提供了一个 Guice 绑定来初始化自己,你似乎没有在你的库中使用它,所以模块无法初始化自己,然后你在运行时得到一个错误。我会将此作为问题报告给 PlaySwagger(应该写在文档中)。

具体情况是:

  1. 在实例化新服务器时,Play 会初始化 Guice
  2. Guice 将寻找任何模块来进行依赖注入
  3. Guice 将注入 SwaggerPlugin(Play Swagger 的)https://github.com/swagger-api/swagger-play/blob/master/play-2.6/swagger-play2/app/play/modules/swagger/SwaggerModule.scala#L11
  4. 服务器已启动
  5. http://localhost:9000/swagger.json GET 请求被处理
  6. Swagger Play 寻找 API 元数据,但从未设置 https://github.com/swagger-api/swagger-play/blob/master/play-2.6/swagger-play2/app/play/modules/swagger/ApiListingCache.scala#L14
  7. Swagger Play 调用的方法试图访问 Swagger Core 库的一个 null 静态变量,Swagger API https://github.com/swagger-api/swagger-core/blob/1.5/modules/swagger-core/src/main/java/io/swagger/config/ScannerFactory.java#L4

为什么那个变量为空?

嗯,Play Swagger 库依赖于 Java lib Swagger Core,因此在设置时它会为静态方法分配一个值,因此期望该变量在运行时设置.

哪里出了问题?

不幸的是PlaySwagger,像Play依赖Guice和Swagger Java lib,带来了Java语言的问题:静态变量和空指针异常。它还依赖于 OpenAPI 2 而不是最近的 OpenAPI 3.

我有什么建议?

也许可以尝试使用iHeartRadio 的Swagger,乍一看它似乎更轻巧而且没有使用Guice。同样根据我的经验,我更喜欢它在 routes 文件上使用 yml 注释而不是注释,这可以防止整个应用程序出现编译和运行时错误,但它会使调试更加困难,因为它无法静默生成swagger.json 文件。我建议您尝试使用替代安装在运行时生成 swagger.json。 Link: https://github.com/iheartradio/play-swagger/blob/master/docs/AlternativeSetup.md

祝你好运,希望对你有所帮助。