0

我已经用 Guice 配置了我的 GWT 应用程序,如此所述。通过此设置,应用程序可以正常工作。

但是,我现在想做的是让 GWTTestCase 使用 GWT RPC 调用服务。为此我做了这个,

  • 更新了我的 <app>JUnit.gwt.rpc 以便服务 URL 映射到 GuiceRemoteServiceServlet
  • 向 GuiceRemoteServiceServlet 添加了一个 init() 方法以根据此注释初始化 Injector

不幸的是,我仍然遇到错误,

com.google.inject.ProvisionException: Guice provision errors:

Caused by: com.google.inject.OutOfScopeException: Cannot access scoped object. Either we are not currently inside an HTTP Servlet request, or you may have forgotten to apply com.google.inject.servlet.GuiceFilter as a servlet filter for this request.
    at com.google.inject.servlet.GuiceFilter.getContext(GuiceFilter.java:132)
    at com.google.inject.servlet.GuiceFilter.getRequest(GuiceFilter.java:118)
    at com.google.inject.servlet.InternalServletModule$1.get(InternalServletModule.java:35)
.....

它试图提供的对象是 ServletContext。错误的原因是 GuiceFilter 没有被调用,所以 ServletContext 没有绑定到 ThreadLocal。

有没有办法克服这个问题?

4

1 回答 1

1

在 Junit 环境中,您通常不会从 servlet 容器中获得两件事:来自 的设置/销毁帮助GuiceServletContextListener和过滤GuiceFilter,因此您需要自己做这些事情。

您基本上需要创建另一个 servlet 来包装您的 servlet 并执行您通常看到的 servlet 容器完成的所有设置/过滤;我推荐的是这样的:

假设您的 servlet 被调用AdriansGuicedGwtServiceServlet。然后在您的测试目录中创建它:

public class TestAdriansGuicedGwtServiceServlet extends AdriansGuicedGwtServiceServlet {
  private GuiceFilter filter;

  @Override
  public void init() {
    super.init();

    // move your injector-creating code here if you want to
    // (I think it's cleaner if you do move it here, instead of leaving
    //  it in your main servlet)

    filter = new GuiceFilter();
    filter.init(new FilterConfig() {
      public String getFilterName() {
        return "GuiceFilter";
      }

      public ServletContext getServletContext() {
        return TestAdriansGuicedGwtServiceServlet.this.getServletContext();
      }

      public String getInitParameter(String s) {
        return null;
      }

      public Enumeration getInitParameterNames() {
        return new Vector(0).elements();
      }
    });
  }

  @Override
  public void destroy() {
    super.destroy();
    filter.destroy();
  }

  private void superService(ServletRequest req, ServletResponse res)
      throws ServletException, IOException {
    super.service(req, res);
  }

  @Override
  public void service(ServletRequest req, ServletResponse res) 
      throws ServletException, IOException {
    filter.doFilter(new FilterChain() {
      public void doFilter (ServletRequest request, ServletResponse response)
          throws IOException, ServletException {
        superService(request, response);
      }
    });
  }
}

然后在你的 <app>Junit.gwt.rpc 中有它映射TestAdriansGuicedGwtServiceServlet而不是你真正的 servlet。

于 2010-05-18T13:49:24.670 回答