Guice将AppEngine devserver模块分解为实例路由

时间:2014-09-23 11:50:24

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

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

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

,我使用“主机”标头将任务路由到第二个应用

如果我使用普通的旧web.xml for 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>

ContextListener:

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);
    }
}

2 个答案:

答案 0 :(得分:2)

首先阅读routing requests on the dev server。确保您的模块已启动并在这些网址上进行回答。然后确保将任务队列路由到正确的模块。

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

答案 1 :(得分:2)

自2013年8月19日以来,过滤器不受后端(现在的模块)的尊重,这是一个众所周知的问题。请在这里投票,https://code.google.com/p/googleappengine/issues/detail?id=9859