/* * Copyright 2008 Jeff Dwyer * * 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. */ package com.apress.progwt.server.gwt; /** * Updated by Jeff Dwyer to add HibernateFilter and allow explicit * Serialization * * Copyright 2006 George Georgovassilis <g.georgovassilis[at]gmail.com> * * 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.ServletContext; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.log4j.Logger; import org.springframework.web.context.ServletContextAware; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.mvc.Controller; import com.apress.progwt.client.domain.GWTSerializer; import com.apress.progwt.client.exception.InfrastructureException; 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.gwt.user.server.rpc.SerializationPolicy; /** * Simple spring controller that merges GWT's {@link RemoteServiceServlet}, * the {@link Controller} and also implements the {@link RemoteService} * interface so as to be able to directly delegate RPC calls to extending * classes. * * @author g.georgovassilis * */ public class GWTController extends RemoteServiceServlet implements ServletContextAware, Controller, RemoteService, GWTSerializer { private static final Logger log = Logger .getLogger(GWTController.class); private static final long serialVersionUID = 5399966488983189122L; private boolean serializeEverything = false; public void setSerializeEverything(boolean serializeEverything) { this.serializeEverything = serializeEverything; } @Override public String processCall(String payload) throws SerializationException { try { RPCRequest rpcRequest = RPC.decodeRequest(payload, this .getClass(), this); ServerSerializationStreamWriter_1_5_3 writer = getWriter(rpcRequest); return RPC1524.invokeAndEncodeResponse(this, rpcRequest .getMethod(), rpcRequest.getParameters(), writer); } catch (IncompatibleRemoteServiceException ex) { log .error( "An IncompatibleRemoteServiceException was thrown while processing this call.", ex); return RPC.encodeResponseForFailure(null, ex); } catch (Exception e){ log .error( "An Exception was thrown while processing this call.", e); return RPC.encodeResponseForFailure(null, e); } } private ServerSerializationStreamWriter_1_5_3 getWriter( RPCRequest rpcRequest) { return getWriter(rpcRequest.getSerializationPolicy()); } /** * would prefer to call doGetSerializationPolicy() so that we could * use the new serializer policies, but not sure how to get the * necessary parameters * * @return */ private ServerSerializationStreamWriter_1_5_3 getWriter() { return getWriter(OneFourTenSerializationPolicy.getInstance()); } private ServerSerializationStreamWriter_1_5_3 getWriter( SerializationPolicy serializationPolicy) { ServerSerializationStreamWriter_1_5_3 writer = new ServerSerializationStreamWriter_1_5_3( serializationPolicy); writer.setValueWriter(Object.class, new ValueWriter() { public void write(ServerSerializationStreamWriter_1_5_3 stream, Object instance) throws SerializationException { stream.writeObject(HibernateFilter.filter(instance)); } }); return writer; } /** * implement GWTSerializer. Used for GWT host pages that want to * serialize objects to bootstrap GWT and prevent needing a startup * async call. */ public String serializeObject(Object object, Class<?> clazz) throws InfrastructureException { ServerSerializationStreamWriter_1_5_3 serializer = getWriter(); try { serializer.serializeValue(object, clazz); } catch (SerializationException e) { throw new InfrastructureException(e); } String bufferStr = "//OK" + serializer.toString(); return bufferStr; } /** * Normal GWT Serialization requires that we do a GWT compile to * create the serialization whitelist. Unfortunately this means we * can't just restart jetty and have this Controller Serialize, unless * we do a gwt compile, which slows us down considerably. Solutions is * to use our funky laissez faire 1.4.10 (RC1) style serialization * policy to serialize everything which means we don't need to * recompile all the gwt stuff just to restart jetty. * * Use the 'serializeEverything' variable which is set differently on * test and deployment machines to go to regular 1.5 serialization * when deployed. */ @Override protected SerializationPolicy doGetSerializationPolicy( HttpServletRequest request, String moduleBaseURL, String strongName) { if (serializeEverything) { log.warn("Using 1.4.10 (RC1) style serializaion."); return OneFourTenSerializationPolicy.getInstance(); } else { log.debug("Using Standard Serialization."); return super.doGetSerializationPolicy(request, moduleBaseURL, strongName); } } public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception { try{ doPost(request, response); return null; }catch (Exception ex) { log.error("handleRequest error "+ex); //ex.printStackTrace(); return null; } } private ServletContext servletContext; public void setServletContext(ServletContext servletContext) { this.servletContext = servletContext; } public ServletContext getServletContext() { return servletContext; } }