/* * Copyright 2008 Pavel Jbanov. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. */ import javax.servlet.ServletException; import org.apache.commons.beanutils.BeanUtils; import com.google.gwt.user.client.rpc.IncompatibleRemoteServiceException; import com.google.gwt.user.client.rpc.RemoteService; import com.google.gwt.user.client.rpc.SerializationException; import com.google.gwt.user.server.rpc.RPC; import com.google.gwt.user.server.rpc.RPCRequest; import com.google.gwt.user.server.rpc.RemoteServiceServlet; import com.google.inject.Guice; import com.google.inject.Injector; import com.google.inject.Module; /** * GuiceRemoteServiceServlet is a wrapper servlet for GWT RPC utilizing Guice for * managing RemoteService implementation object's lifecycle. * * This servlet requires one parameter: * guice.module - class name of the guice module. Used for instantiation of * Guice injector. * */ @SuppressWarnings("serial") public class GuiceRemoteServiceServlet extends RemoteServiceServlet { private static final String INJECTOR_ATTR_NAME = "___GuiceRemoteServiceServlet_GWT_injector"; @SuppressWarnings("unchecked") @Override public void init() throws ServletException { super.init(); String guiceModuleClassName = getInitParameter("guice.module"); Class
module; try { module = (Class
) Class.forName(guiceModuleClassName); Injector injector = Guice.createInjector(module.newInstance()); getServletContext().setAttribute(INJECTOR_ATTR_NAME, injector); } catch (Exception e) { throw new RuntimeException(e.getMessage(), e); } } @Override public String processCall(String payload) throws SerializationException { try { RPCRequest rpcRequest = RPC.decodeRequest(payload); RemoteService service = getServiceInstance(rpcRequest.getMethod().getDeclaringClass()); return RPC.invokeAndEncodeResponse(service, rpcRequest.getMethod(), rpcRequest.getParameters(), rpcRequest.getSerializationPolicy()); } catch (IncompatibleRemoteServiceException ex) { getServletContext() .log("An IncompatibleRemoteServiceException was thrown while processing this call.", ex); return RPC.encodeResponseForFailure(null, ex); } } private Injector getInjector() { return (Injector) getServletContext().getAttribute(INJECTOR_ATTR_NAME); } @SuppressWarnings("unchecked") private RemoteService getServiceInstance(Class serviceClass) { try { RemoteService remoteService = (RemoteService) getInjector().getInstance(serviceClass); // if the service needs request and/or response then it can expose // setters for httpServletRequest and/or httpServletResponse and we'll inject them. try { BeanUtils.setProperty(remoteService, "httpServletRequest", getThreadLocalRequest()); } catch (Exception e) {/* do nothing */} try { BeanUtils.setProperty(remoteService, "httpServletResponse", getThreadLocalResponse()); } catch (Exception e) {/* do nothing */} return remoteService; } catch (Exception e) { throw new RuntimeException(e.getMessage(), e); } } }