使用Guice在GWTTestCase中使用GWT RPC

时间:2010-05-14 20:22:28

标签: gwt guice

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

然而,我现在要做的是获取GWTTestCase以使用GWT RPC调用服务。为此我完成了这个,

  • 更新了我的< app> JUnit.gwt.rpc,以便服务网址映射到GuiceRemoteServiceServlet
  • 向GuiceRemoteServiceServlet添加了一个init()方法,以按this comment初始化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。

有没有办法解决这个问题?

1 个答案:

答案 0 :(得分:1)

在Junit环境中,您没有从servlet容器中获得两件事:来自GuiceServletContextListener的setup / destroy帮助和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。