【问题标题】:Guice breaks AppEngine devserver module to instance routingGuice 将 AppEngine 开发服务器模块分解为实例路由
【发布时间】:2014-09-23 11:50:23
【问题描述】:

我在应用程序中有两个模块。第一个模块正在通过推送队列为第二个模块生成任务。两个模块都使用手动缩放。

Queue queue = QueueFactory.getQueue("update-job");
ModulesService ms = ModulesServiceFactory.getModulesService();
queue.add(TaskOptions.Builder.withUrl("/update-job").header("Host", ms.getVersionHostname("batch", ms.getCurrentVersion())));

由于这个错误https://code.google.com/p/googleappengine/issues/detail?id=10954,我使用“Host”标头将任务路由到第二个应用程序@

如果我使用普通的旧 web.xml 进行 servlet 到 url 的映射,一切正常,所有对版本主机的请求都将成功路由到实例并执行。 但是如果我切换到 GuiceFilter 相同的请求将在版本 url 上产生 404。它们在实例 url 上仍然可用,但不会从版本 url 自动路由。 两种配置都可以在生产环境中正常运行,只有 devserver 受到影响。

我显然遗漏了一些东西,因为我找不到关于这个问题的任何信息。

我尝试了不同的 guice 和 guice-servlet 版本:3.0、3.0.1-SNAPSHOT、3.1.0-SNAPSHOT、4.0-beta4 - 没有结果

也尝试过这种方法https://stackoverflow.com/a/9706953/4070223 - 没有结果

这就是 web.xml 的样子:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" version="2.5">
<filter> <!-- does not work -->
    <filter-name>guiceFilter</filter-name>
    <filter-class>com.google.inject.servlet.GuiceFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>guiceFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

<!--<servlet>-->  <!-- works fine -->
    <!--<servlet-name>update-job</servlet-name>-->
    <!--<servlet-class>com.company.UpdateJobServlet</servlet-class>-->
<!--</servlet>-->
<!--<servlet-mapping>-->
    <!--<servlet-name>update-job</servlet-name>-->
    <!--<url-pattern>/update-job</url-pattern>-->
<!--</servlet-mapping>-->

<welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
</welcome-file-list>

<listener>
    <listener-class>com.company.BatchContextListener</listener-class>
</listener>
</web-app>

上下文监听器:

public class BatchContextListener extends com.google.inject.servlet.GuiceServletContextListener {
    @Override
    protected Injector getInjector() {
        return Guice.createInjector(new BatchModule());
    }
}

和模块:

public class BatchModule extends ServletModule {
    @Override
    protected void configureServlets() {
        serve("/update-job").with(UpdateJobServlet.class);
    }
}

【问题讨论】:

  • 你没有显示你用来构建注入器的guice模块吗? guice 是魔法,但魔法需要你的一些咒语。
  • @JarrodRoberson 模块非常简单。已编辑帖子。
  • 该绑定中没有任何版本信息,您为什么认为它会神奇地推断出 /update-job 之后的任何内容?
  • @JarrodRoberson 绑定中的版本信息是什么意思?不太明白。例如,我的绑定与此处的github.com/google/guice/wiki/GoogleAppEngine 相同。

标签: google-app-engine guice guice-servlet


【解决方案1】:

自 2013 年 8 月 19 日起,后端(现为模块)不支持过滤器是一个已知问题。请在此处投票,https://code.google.com/p/googleappengine/issues/detail?id=9859

【讨论】:

  • 在访问过滤器提供的 URL 时,我遇到了类似的问题,即 Blobstore 上传回调不起作用(意味着返回 404)。仅在开发服务器中。开发服务器似乎没有很好地考虑过滤器。
  • 您的问题是附加模块还是默认模块?
  • 我不使用模块。至少不明确。
  • 我会鼓励你使用应用引擎版本 1.9.46 来解决这个问题,我在将 Guice 与 GAE 1.9.37 集成时遇到了类似的问题,但在我将项目升级到 1.9 后问题就消失了。 46
【解决方案2】:

首先阅读routing requests on the dev server。确保您的模块已启动并响应这些网址。然后确保任务队列被路由到正确的模块。

或者:使用 target directive in the queues.xml 代替 Host 标头。我相信这是一种更简洁的方法,因为您不会因路由细节而污染源代码。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-06-09
    • 2016-11-06
    • 1970-01-01
    • 2014-05-20
    • 2021-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多