Skip to content

Instantly share code, notes, and snippets.

@skhatri
Created March 1, 2012 13:06
Show Gist options
  • Save skhatri/1949709 to your computer and use it in GitHub Desktop.
Save skhatri/1949709 to your computer and use it in GitHub Desktop.
GWT Integration with Spring without Servlet
package com.app.web;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import com.google.web.bindery.requestfactory.server.ServiceLayerDecorator;
import com.google.web.bindery.requestfactory.shared.Locator;
import com.google.web.bindery.requestfactory.shared.RequestContext;
import com.google.web.bindery.requestfactory.shared.ServiceLocator;
@Service
public class DefaultServiceLayerDecorator extends ServiceLayerDecorator {
@Autowired
private ApplicationContext context;
@Override
public <T extends Locator<?, ?>> T createLocator(Class<T> clazz) {
return context.getBean(clazz);
}
@Override
public <T extends ServiceLocator> T createServiceLocator(Class<T> clazz) {
T locator = context.getBean(clazz);
return locator;
}
@Override
public Object createServiceInstance(
Class<? extends RequestContext> requestContext) {
Class<?> requestClass = resolveServiceClass(requestContext);
return context.getBean(requestClass);
}
}
package com.app.web;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import com.google.web.bindery.requestfactory.shared.ServiceLocator;
@Service
public class DefaultServiceLocator implements ServiceLocator {
@Autowired
ApplicationContext applicationContext;
@Override
public Object getInstance(Class<?> clazz) {
return applicationContext.getBean(clazz);
}
}
package com.app.web;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import com.google.gwt.user.server.rpc.RPCServletUtils;
import com.google.web.bindery.requestfactory.server.DefaultExceptionHandler;
import com.google.web.bindery.requestfactory.server.ExceptionHandler;
import com.google.web.bindery.requestfactory.server.RequestFactoryServlet;
import com.google.web.bindery.requestfactory.server.ServiceLayer;
import com.google.web.bindery.requestfactory.server.ServiceLayerDecorator;
import com.google.web.bindery.requestfactory.server.SimpleRequestProcessor;
import com.google.web.bindery.requestfactory.shared.RequestFactory;
@RequestMapping("/gwtRequest")
@Controller
public class RequestFactoryController {
private static final boolean DUMP_PAYLOAD = Boolean.getBoolean("gwt.rpc.dumpPayload");
private static final String JSON_CHARSET = "UTF-8";
private static final String JSON_CONTENT_TYPE = "application/json";
private static final Logger log = Logger.getLogger(RequestFactoryServlet.class.getCanonicalName());
/**
* These ThreadLocals are used to allow service objects to obtain access to
* the HTTP transaction.
*/
private static final ThreadLocal<ServletContext> perThreadContext =
new ThreadLocal<ServletContext>();
private static final ThreadLocal<HttpServletRequest> perThreadRequest =
new ThreadLocal<HttpServletRequest>();
private static final ThreadLocal<HttpServletResponse> perThreadResponse =
new ThreadLocal<HttpServletResponse>();
/**
* Returns the thread-local {@link HttpServletRequest}.
*
* @return an {@link HttpServletRequest} instance
*/
public static HttpServletRequest getThreadLocalRequest() {
return perThreadRequest.get();
}
/**
* Returns the thread-local {@link HttpServletResponse}.
*
* @return an {@link HttpServletResponse} instance
*/
public static HttpServletResponse getThreadLocalResponse() {
return perThreadResponse.get();
}
/**
* Returns the thread-local {@link ServletContext}
*
* @return the {@link ServletContext} associated with this servlet
*/
public static ServletContext getThreadLocalServletContext() {
return perThreadContext.get();
}
private final SimpleRequestProcessor processor;
/**
* Constructs a new {@link RequestFactoryServlet} with a
* {@code DefaultExceptionHandler}.
*/
//Autowire annotation added
//rest of the code is as is from RequestFactoryServlet
@Autowired
public RequestFactoryController(ServiceLayerDecorator serviceLayerDecorator) {
this(new DefaultExceptionHandler(), serviceLayerDecorator);
}
/**
* Use this constructor in subclasses to provide a custom
* {@link ExceptionHandler}.
*
* @param exceptionHandler an {@link ExceptionHandler} instance
* @param serviceDecorators an array of ServiceLayerDecorators that change how
* the RequestFactory request processor interact with the domain
* objects
*/
public RequestFactoryController(ExceptionHandler exceptionHandler,
ServiceLayerDecorator... serviceDecorators) {
processor = new SimpleRequestProcessor(ServiceLayer.create(serviceDecorators));
processor.setExceptionHandler(exceptionHandler);
}
/**
* Processes a POST to the server.
*
* @param request an {@link HttpServletRequest} instance
* @param response an {@link HttpServletResponse} instance
* @throws IOException if an internal I/O error occurs
* @throws ServletException if an error occurs in the servlet
*/
@RequestMapping(method=RequestMethod.POST)
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
perThreadContext.set(request.getSession().getServletContext());
perThreadRequest.set(request);
perThreadResponse.set(response);
// No new code should be placed outside of this try block.
try {
String jsonRequestString =
RPCServletUtils.readContent(request, JSON_CONTENT_TYPE, JSON_CHARSET);
if (DUMP_PAYLOAD) {
System.out.println(">>> " + jsonRequestString);
}
try {
String payload = processor.process(jsonRequestString);
if (DUMP_PAYLOAD) {
System.out.println("<<< " + payload);
}
response.setStatus(HttpServletResponse.SC_OK);
response.setContentType(RequestFactory.JSON_CONTENT_TYPE_UTF8);
// The Writer must be obtained after setting the content type
PrintWriter writer = response.getWriter();
writer.print(payload);
writer.flush();
} catch (RuntimeException e) {
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
log.log(Level.SEVERE, "Unexpected error", e);
}
} finally {
perThreadContext.set(null);
perThreadRequest.set(null);
perThreadResponse.set(null);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment