• Home

GWT RPC implementation via Command pattern need only one! GWT RPC service for all kind of implementations:

GWT RPC service
@RemoteServiceRelativePath("custom.rpc") public interface CustomRemoteService extends RemoteService { Response send(Request request) throws Exception; } public interface CustomRemoteServiceAsync { void send(Request request, AsyncCallback callback); }

For all requests we have one single entry point at server:

Controller (Spring MVC)
package com.bc.capman.web.common.server.controller; import com.bc.capman.web.common.server.rpc.RpcHandler; import com.bc.capman.web.common.shared.rpc.Request; import com.bc.capman.web.common.shared.rpc.Response; import com.bc.capman.web.common.shared.state.StateException; import com.google.gwt.user.server.rpc.RemoteServiceServlet; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.mvc.Controller; import javax.inject.Inject; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.HashMap; import java.util.Map; /** * User: Grigory Kislin * Date: 27/06/11 */ public class GwtRpcController extends RemoteServiceServlet implements Controller { private static Map, RpcHandler> requestMap = new HashMap<>(); @Inject private ServletContext servletContext; @Override public ServletContext getServletContext() { return servletContext; } @Override public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception { doPost(request, response); return null; } @Override public Response send(Request request) { try { logger.debug(...); RpcHandler handler = requestMap.get(request.getClass()); return handler.handlerRequest(request); } catch (StateException se) { ... } finally { logger.debug(...); } } public static void registerHandler(Class requestClass, RpcHandler handler) { assert requestMap.get(requestClass) == null : "Handler with request " + requestClass + " already registered"; requestMap.put(requestClass, (RpcHandler) handler); } }

All handlers RpcHandler inherit RpcHandlerImpl base realization and registered own request in RpcHandlerImpl constructor:

Handler interface (Command)
public interface RpcHandler { RS handlerRequest(RQ request) throws Exception; }

Handler base realization
public abstract class RpcHandlerImpl implements RpcHandler { @Inject protected ContextHolder contextHolder; public RpcHandlerImpl(Class requestClass) { GwtRpcController.registerHandler(requestClass, this); } }

    So for the new custom request we need to create:
  1. CustomRequest extends Request - java bean with all necessary information (do not forget default constructor for GWT serialization)
  2. (Optional) CustomResponse extends Response - use custom or standard response for pass information to client
  3. CustomHandler extends RpcHandlerImpl - handler for handle request and registered ourselves in constructor
  4. public CustomHandler() { super(CustomRequest.class); }

All logging, time measurement, exception and context handling now located in 2 classes: GwtRpcController and RpcHandlerImpl.