首页 > 解决方案 > 如何将 Jersey REST 服务器部署到 Heroku

问题描述

Jersey 的“入门”示例使用了 Grizzly,因此我们采用了该示例。这使我们能够以一种相当直接的方式配置身份验证,因此:

private static final String BASE_URI = "http://localhost:8080/rest/";

// com.ourapp.AuthFilter is a javax.ws.rs.container.ContainerRequestContext
final ResourceConfig rc = new ResourceConfig(com.ourapp.AuthFilter.class).packages("com.ourapp");

// create and start a new instance of grizzly http server
// exposing the Jersey application at BASE_URI
final HttpServer server = GrizzlyHttpServerFactory.createHttpServer(URI.create(BASE_URI), rc);

所有这些都在本地工作,这给了我们很大的希望。

可悲的是,当我们将所有这些部署到 Heroku 时,我们遇到了BASE_URI. 我们尝试了各种各样的 URI,但在启动时遇到了 Heroku 的运行时异常,例如:

javax.ws.rs.ProcessingException: Failed to start Grizzly HTTP server: Permission denied

javax.ws.rs.ProcessingException: Failed to start Grizzly HTTP server: Cannot assign requested address

最后,我们决定放弃 Grizzly 并尝试由 Jersey 文档提供的Jetty 解决方案。

令人惊讶的是,文档中提供的 Maven 原型根本无法编译,直接开箱即用。

mvn archetype:generate -DarchetypeArtifactId=jersey-quickstart-grizzly2 \
-DarchetypeGroupId=org.glassfish.jersey.archetypes -DinteractiveMode=false \
-DgroupId=com.example -DartifactId=simple-service -Dpackage=com.example \
-DarchetypeVersion=2.28

具体来说:

    root.setContextPath("/");
    root.setResourceBase(webappDirLocation);
    server.setHandler(root);

完全未定义,并且

    server.start();

需要类型的参数LifeCycle

那么,有人可以帮我让 Grizzly 在 Heroku 上工作吗?如果做不到这一点,谁能告诉我 Jetty 应用程序的正确配置是什么,以及如何获得一个类型的过滤器javax.ws.rs.container.ContainerRequestContext来使用 Jetty 完成它的工作?

标签: javaherokujerseyjettygrizzly

解决方案


许多小时,几十种不同事物的随机组合,然后是大块头发......

    final String port = System.getenv("PORT");
    final String baseUri = "http://0.0.0.0:" + port;
    final HttpServer server = GrizzlyHttpServerFactory.createHttpServer(URI.create(baseUri), rc);

并且,在 Procfile 中:

web: java $JAVA_OPTS -Dserver.port=$PORT -cp target/classes:target/dependency/* com.ourapp.Main

它使我们的 Heroku 在启动时为应用程序分配一个随机端口号,必须像这样将其传递给 Grizzly。哦,那 0.0.0.0 的东西似乎只是没有记录。


推荐阅读