package org.jboss.resteasy.springmvc; import org.jboss.resteasy.core.AsynchronousDispatcher; import org.jboss.resteasy.core.ServerResponseWriter; import org.jboss.resteasy.core.SynchronousDispatcher; import org.jboss.resteasy.specimpl.BuiltResponse; import org.jboss.resteasy.spi.HttpRequest; import org.jboss.resteasy.spi.HttpResponse; import org.jboss.resteasy.spi.ResteasyDeployment; import org.jboss.resteasy.spi.UnhandledException; import org.springframework.web.servlet.HandlerAdapter; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.View; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; /** * @author <a href="mailto:sduskis@gmail.com">Solomn Duskis</a> * @version $Revision: 1 $ */ // TODO: Right now there's a problematic relationship between Dispatcher and // Registry. Ideally, the Registry shouldn't be owned by the Dispatcher, and the // methods needed from SynchronousDispatcher should move into a shared class. public class ResteasyHandlerAdapter extends ResteasyWebHandlerTemplate<ModelAndView> implements HandlerAdapter { protected ResteasyDeployment deployment; public ResteasyHandlerAdapter(ResteasyDeployment deployment) { super(deployment.getProviderFactory()); this.deployment = deployment; } public long getLastModified(HttpServletRequest request, Object handler) { return -1; } public ModelAndView handle(HttpServletRequest servletRequest, HttpServletResponse servletResponse, Object handler) throws Exception { ResteasyRequestWrapper requestWrapper = (ResteasyRequestWrapper) handler; // super.handle wraps the handle call you see below return super.handle(requestWrapper, servletResponse); } protected ModelAndView handle(ResteasyRequestWrapper requestWrapper, HttpResponse response) throws IOException { SynchronousDispatcher dispatcher = (SynchronousDispatcher)deployment.getDispatcher(); if (requestWrapper.getErrorCode() != null) { try { response.sendError(requestWrapper.getErrorCode(), requestWrapper .getErrorMessage()); } catch (Exception e) { throw new UnhandledException(e); } return null; } if (requestWrapper.getAbortedResponse() != null) { ServerResponseWriter.writeNomapResponse(((BuiltResponse) requestWrapper.getAbortedResponse()), requestWrapper.getHttpRequest(), response, dispatcher.getProviderFactory()); return null; } HttpRequest request = requestWrapper.getHttpRequest(); if (dispatcher instanceof AsynchronousDispatcher) { AsynchronousDispatcher asyncDispatcher = (AsynchronousDispatcher) dispatcher; if (asyncDispatcher.isAsynchrnousRequest(request)) { asyncDispatcher.invoke(request, response); return null; } } return createModelAndView(requestWrapper, response); } protected ModelAndView createModelAndView( ResteasyRequestWrapper requestWrapper, HttpResponse response) { HttpRequest request = requestWrapper.getHttpRequest(); SynchronousDispatcher dispatcher = (SynchronousDispatcher)deployment.getDispatcher(); dispatcher.pushContextObjects(request, response); try { BuiltResponse jaxrsResponse = null; try { jaxrsResponse = (BuiltResponse) requestWrapper.getInvoker().invoke(request, response); } catch (Exception e) { dispatcher.writeException(request, response, e); } if (jaxrsResponse == null) return null; try { Object entity = jaxrsResponse.getEntity(); if (entity instanceof ModelAndView) { ServerResponseWriter.commitHeaders(jaxrsResponse, response); return (ModelAndView) entity; } return createModelAndView(jaxrsResponse); } catch (Exception e) { dispatcher.writeException(request, response, e); return null; } } finally { dispatcher.clearContextData(); } } protected ModelAndView createModelAndView(BuiltResponse serverResponse) { View view = createView(serverResponse); return new ModelAndView(view, "responseInvoker", serverResponse); } protected View createView(BuiltResponse serverResponse) { String contentType = ServerResponseWriter.resolveContentType(serverResponse).toString(); return new ResteasyView(contentType, deployment); } public boolean supports(Object handler) { return handler instanceof ResteasyRequestWrapper; } }