Question

I have some questions regarding gwt-dispatch and guice. I'm using Guice 2.0, gwt-dispatch 1.1.0 snapshot, mvp4g 1.1.0 and GIN 1.0

First of all, I have defined simple action, result and handler:

ListContactsAction.java

public class ListContactsAction implements Action<ListContactsResult>{

    public ListContactsAction() {
    }

}

ListContactsResult.java

public class ListContactsResult implements Result {

    private List<Contact> contactList;

    public ListContactsResult() {
    }

    public ListContactsResult(List<Contact> contactList) {
        this.contactList = contactList;
    }

    public List<Contact> getContactList() {
        return contactList;
    }
}

ListContactsHandler.java

public class ListContactsHandler implements ActionHandler<ListContactsAction, ListContactsResult>{

    @Inject
    private SqlSessionFactory factory;

    public Class<ListContactsAction> getActionType() {
        return ListContactsAction.class;
    }

    public ListContactsResult execute(ListContactsAction a, ExecutionContext ec) throws DispatchException {
        // some code using SqlSessionFactory and returning ListContactResult
        // with list of contacts
    }

    public void rollback(ListContactsAction a, ListContactsResult r, ExecutionContext ec) throws DispatchException {
        /* get action - no rollback needed */
    }

}

In previous version of my app, which was using rpc service instead of command pattern, I had a method which was providing SqlSessionFactory for injections, something like this:

@Provides
    public SqlSessionFactory getSqlSessionFactory(){
        // some code here
    }

I read on gwt-dispatch getting started that I have to provide binding between my action and it's handler, which should look something like that:

public class ContactModule extends ActionHandlerModule{
    @Override
    protected void configureHandlers() {
        bindHandler(ListContactsAction.class, ListContactsHandler.class);
    }
}

But I have problem wiring it all with Guice, because this example from gwt-dispatch site:

public class DispatchServletModule extends ServletModule {
    @Override
    public void configureServlets() {
        serve( "/path/to/dispatch" ).with( DispatchServiceServlet.class );
    }
}

doesn't work, since there is no DispatchServiceServlet in the package.

My questions are:

  • How should I write DispatchServletModule and how to make it going (with what I should serve path)
  • what should I put in the web.xml file of my app to be able to correctly execute actions from my presenter, which has GIN injected DispatcherAsync implementation
  • Where should I put my SqlSessionFactory providing method (in which module) to be able to inject SqlSessionFactory where I need it
  • How I instantiate the injector so then I can use it in other action handlers properly

I think that is all and I made myself clear. If something isn't clear enough, I'll try to be more specific.

No correct solution

OTHER TIPS

Have you created a GuiceServletConfig class? This is where you setup your Dispatch servlet module as well as your action handler module with Guice.

plubic class GuiceServletConfig extends GuiceServletContextListener {
    @Override
    protected Injector getInjector() {
        return Guice.createInjector(new HandlerModule(), new DispatchServletModule());
    }
}

The HandlerModule is your ActionHandler module class, so from your code you would put your ContactModule class.

For your SqlSessionFactory, you could setup the binding for it in your ContactModule, with my code I only have a single ServerModule that sets up all my service and action handler bindings. This is mainly for the sake of simplicity.

GWT-Platform framework uses a gwt-dispatch fork to handle rpc requests. There's a lot of code, which you probably had to wtite yourself, if you think of seriously using dispatcher and Guice. I highly recommend it.

Firstly, I sympathise. Putting this all together isn't documented in any one spot. I'll answer each of your questions in turn. Add comments to my answer if any of it is unclear.

QU: How should I write DispatchServletModule and how to make it going (with what I should serve path)?

There's a GuiceStandardDispatchServlet class in the net.customware.gwt.dispatch.server.guice package; use that. I'm not 100 percent sure why, but the path I use includes the name of my GWT module, followed by '/dispatch'. You might have to experiment with that.

public class MyServletModule extends ServletModule {
  @Override protected void configureServlets() {
    serve("/com.my.module.name/dispatch")
      .with(GuiceStandardDispatchServlet.class);
  }
}

QU: what should I put in the web.xml file of my app to be able to correctly execute actions from my presenter, which has GIN injected DispatcherAsync implementation?

<?xml version="1.0" encoding="UTF-8"?>
<web-app>
  <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>
  <listener>
    <listener-class>com.myapp.whatever.MyContextListener</listener-class>
  </listener>
  ...
</web-app>

... and then you'll need a custom context listener that creates a Guice injector as follows. Notice that I've included your ContactModule, which binds action handlers.

public class MyContextListener extends GuiceServletContextListener {
  @Override protected Injector getInjector() {
    return Guice.createInjector(new MyServletModule(), 
      new ContactModule(), new SQLStuffModule());
  }
}

QU: Where should I put my SqlSessionFactory providing method (in which module) to be able to inject SqlSessionFactory where I need it?

Notice that I included a new SQLStuffModule in the previous code snippet; that would be a good place to put your SqlSessionFactory binding. There's no harm having multiple modules, and I find that it keeps the various concerns nicely separated.

QU: How I instantiate the injector so then I can use it in other action handlers properly?

For the server-side, see the MyContextListener code snippet above.

On the client side, you'll need a custom injector interface something like this:

@GinModules(StandardDispatchModule.class, MyClientModule.class)
public interface MyGinjector extends Ginjector {
  MyWidgetMainPanel getMainPanel();
}

...and you can bind your MVP stuff in a custom Gin module as follows. I'm sorry that I'm not familiar with mvp4g, but I assume that you'll need to wire the views and presenters together in the module class.

public class MyClientModule extends AbstractGinModule {
  @Override protected void configure() {
    bind(...).to(...);
    ...
  }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top