Question

We had been using GWT-Dispatch to support the RPC calls using command patterns. We now need to move to GWTP since Dispatch has been absorbed into that project. Would seem to be all well and good. The problem is that we are unable to get a DispatchAsync object anymore. In Dispatch, it was extremely simple to get the default implementation:

private final DispatchAsync dispatchAsync = GWT.create(DefaultDispatchAsync.class);

This no longer works. DefaultDispatchAsync is deprecated, and when we use the suggested replacement for it (RpcDispatchAsync) it looks like this:

private final DispatchAsync dispatchAsync = GWT.create(RpcDispatchAsync.class);

we get the following error:

 Rebind result 'com.gwtplatform.dispatch.rpc.client.RpcDispatchAsync' has no default (zero   argument) constructors.

Does anyone have an idea about how to do this? I know if we rewrite all the pages to use the GWTP MVP pattern that it's available in the Presenter but moving things over to use full GWTP is a long process and if we can't get the RPC calls up and working quickly that will be a problem for the project.

Thanks in advance -- hopefully it's something easy.

Was it helpful?

Solution

DispatchAsync is no longer generated via deferred binding. Thus you can’t use GWT.create to instantiate it.

GWTP Dispatch is making heavy use of GIN/Guice. So I would recommend that you use this dependency injection framework to get GWTP Dispatch work.

Here is an example, which provides easy access to the DispatchAsync (without the need of rewriting all pages to use the GWTP MVP Pattern):

[Note: This example uses gwtp dispatch 1.0.3]

Client:

MyClientModule.java - configure injection-rules for DispatchAsync

import com.google.gwt.inject.client.AbstractGinModule;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;
import com.gwtplatform.dispatch.client.DefaultExceptionHandler;
import com.gwtplatform.dispatch.client.DefaultSecurityCookieAccessor;
import com.gwtplatform.dispatch.client.ExceptionHandler;
import com.gwtplatform.dispatch.client.RpcDispatchAsync;
import com.gwtplatform.dispatch.client.actionhandler.ClientActionHandlerRegistry;
import com.gwtplatform.dispatch.client.actionhandler.DefaultClientActionHandlerRegistry;
import com.gwtplatform.dispatch.shared.DispatchAsync;
import com.gwtplatform.dispatch.shared.SecurityCookie;
import com.gwtplatform.dispatch.shared.SecurityCookieAccessor;

public class MyClientModule extends AbstractGinModule {

    private static final String COOKIE_NAME = "JSESSIONID";

    @Override
    protected void configure() {
        bindConstant().annotatedWith(SecurityCookie.class).to(COOKIE_NAME);
        bind(ExceptionHandler.class).to(DefaultExceptionHandler.class);
        bind(SecurityCookieAccessor.class).to(DefaultSecurityCookieAccessor.class);
        bind(ClientActionHandlerRegistry.class).to(DefaultClientActionHandlerRegistry.class);
        bind(DispatchAsync.class).toProvider(DispatchAsyncProvider.class).in(Singleton.class);
    }

    public static class DispatchAsyncProvider implements Provider<DispatchAsync> {

        private final DispatchAsync fDispatchAsync;

        @Inject
        public DispatchAsyncProvider(ExceptionHandler eh, SecurityCookieAccessor sca, ClientActionHandlerRegistry cahr) {
            this.fDispatchAsync = new RpcDispatchAsync(eh, sca, cahr);
        }

        @Override
        public DispatchAsync get() {
            return fDispatchAsync;
        }
    }
}

MyClientInjector.java - injector provides access to DispatchAsync

import com.google.gwt.inject.client.GinModules;
import com.google.gwt.inject.client.Ginjector;
import com.gwtplatform.dispatch.shared.DispatchAsync;

@GinModules(MyClientModule.class)
public interface MyClientInjector extends Ginjector {

    DispatchAsync getDispatchAsync();

}

Server:

MyGuiceServletContextListener.java - create injector for the servlet, which receives the commands and the servermodule, in which the bindings between (clientside) command and (serverside) handler are defined.

import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.servlet.GuiceServletContextListener;

public class MyGuiceServletContextListener extends GuiceServletContextListener {

    @Override
    protected Injector getInjector() {
        return Guice.createInjector(new ServerModule(), new DispatchServletModule());
    }
}

DispatchServletModule.java - configures the servlet, which receives the commands

import com.google.inject.servlet.ServletModule;
import com.gwtplatform.dispatch.server.guice.DispatchServiceImpl;
import com.gwtplatform.dispatch.server.guice.HttpSessionSecurityCookieFilter;
import com.gwtplatform.dispatch.shared.Action;
import com.gwtplatform.dispatch.shared.SecurityCookie;

public class DispatchServletModule extends ServletModule {

    @Override
    public void configureServlets() {
        bindConstant().annotatedWith(SecurityCookie.class).to("JSESSIONID");
        filter("*").through(HttpSessionSecurityCookieFilter.class);
        serve("/" + Action.DEFAULT_SERVICE_NAME + "*").with(DispatchServiceImpl.class);
    }

}

ServerModule.java - bindings between (clientside) command and (serverside) handler

import com.gwtplatform.dispatch.server.guice.HandlerModule;

public class ServerModule extends HandlerModule {

    @Override
    protected void configureHandlers() {
        bindHandler(YourCommand.class, YourHandler.class);
    }
}

web.xml - tell the web-server to use MyGuiceServletContextListener

<filter>
    <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>

<!--
This Guice listener hijacks all further filters and servlets. Extra
filters and servlets have to be configured in your
ServletModule#configureServlets() by calling
serve(String).with(Class<? extends HttpServlet>) and
filter(String).through(Class<? extends Filter)
-->
<listener>
    <listener-class>de.gwtpdispatch.server.MyGuiceServletContextListener</listener-class>
</listener>

Usage

Now you can create the injector with deferred binding and get access to the DispatchAsync-instance:

MyClientInjector injector = GWT.create(MyClientInjector.class);
injector.getDispatchAsync().execute(...YourCommand...)

(AND: Don't forget to include the jars of GIN and Guice in your project and add the gin-module to the project's gwt.xml)

I hope this explanation is detailed enough. Happy coding :)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top