de.swm.gwt.server.MobileRemoteServiceServlet Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of swm-gwt-client Show documentation
Show all versions of swm-gwt-client Show documentation
Plain GWT Swm erweiterungen, auch zur benutzung in mobilen Geraeten
package de.swm.gwt.server;
import java.io.IOException;
import java.net.URLDecoder;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.google.gwt.user.client.rpc.IncompatibleRemoteServiceException;
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.RPCServletUtils;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;
import com.google.gwt.user.server.rpc.SerializationPolicy;
/**
* Implementierung des {@link RemoteServiceServlet} der sowohl JsonP Requests handeln kann (cross domain RPC) als auch
* GWT RPC vom lokalen Dateisystem z.B. mit PhoneGap.
*
*
*
* Beispiel zur Nutzung (wenn JsonP angeschaltet ist):
* Legende:
* __ wird ersetzt als -
* _ wird ersetzt als .
* X wird ersetzt als /
*
*
*
*
*
*
*
*
*
*
*
*
*
*
* Adapted from: http://timepedia.blogspot.com/2009/04/gwt-rpc-over-arbitrary-transports -uber.html , resp.
* http://blog.daniel-kurka.de/2011/01/gwt-rpc-with-phonegap.html
*
* @author wiese.daniel
* copyright (C) 2011, SWM Services GmbH
*
*/
public class MobileRemoteServiceServlet extends RemoteServiceServlet {
private static final int HTTPS_PORT = 443;
private static final int HTTP_PORT = 80;
private static final String IS_POST = "POST";
private static final long serialVersionUID = 1L;
/**
* The request parameter for the gwt-rpc payload.
*/
public static final String RPC_PAYLOAD_PARAM = "rpcpayload";
/**
* The callback parameter for the JSONP callback.
*/
public static final String CALLBACK_PARAM = "callback";
/**
* The actual callback function name that will be retrieved from the {@link HttpServletRequest}.
*/
private String callbackFunction;
private final boolean isJsonp;
/**
* Default constructor - jsonp disabled.
*
*/
public MobileRemoteServiceServlet() {
this(false);
}
/**
* Default constructor.
*
* @param isJsonp
* true wenn JsonP, ansonsten GWT RPC
*/
public MobileRemoteServiceServlet(boolean isJsonp) {
this.isJsonp = isJsonp;
}
@Override
protected void doGet(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse)
throws ServletException, IOException {
if (isJsonp) {
doPost(httpServletRequest, httpServletResponse);
}
}
/**
* Override this method in order to control the parsing of the incoming request.
*
* {@inheritDoc}
*/
@Override
protected String readContent(HttpServletRequest httpServletRequest) throws ServletException, IOException {
if (isJsonp) {
// grab the GWT-RPC payload string from the request
String str = httpServletRequest.getMethod().equals(IS_POST) ? RPCServletUtils
.readContentAsGwtRpc(httpServletRequest) : httpServletRequest.getParameter(RPC_PAYLOAD_PARAM);
// decode it
String ustr = URLDecoder.decode(str, "UTF-8");
// retrieve the callback parameters from the request as well. This will
// be used when padding the JSON response
callbackFunction = httpServletRequest.getParameter(CALLBACK_PARAM);
return ustr;
} else {
return super.readContent(httpServletRequest);
}
}
/**
* Hilfsmethode für {@see #doGetSerializationPolicy(HttpServletRequest, String, String)},
* um den Aufruf von GWT-RPC aus Webanwendungen zu ermöglichen, die im Client im Filesystem
* abgelegt sind. Berechnet die korrekte Modul-Basis-Url auf dem Server.
*
* @param request
* der HTTP-Request
* @param moduleName
* der Modulname
* @return die Basis URL auf dem Server
*/
private String getBaseUrl(HttpServletRequest request, String moduleName) {
if (request.getServerPort() == HTTP_PORT || request.getServerPort() == HTTPS_PORT) {
return request.getScheme() + "://" + "127.0.0.1" + request.getContextPath() + "/" + moduleName + "/";
} else {
return request.getScheme() + "://" + "127.0.0.1" + ":" + request.getServerPort() + request.getContextPath()
+ "/" + moduleName + "/";
}
}
/**
* Ermöglicht den Aufruf von GWT-RPC aus Webanwendungen, die im Client im Filesystem abgelegt sind
* (insb. PhoneGap).
* Ohne diese Methodenüberschreibung sucht GWT die benötigten Steuerdateien für
* die Serialisierung (xxx.gwt.rpc) an der falschen Stelle (an der Stelle, an der sie im Client
* im Filesystem abgelegt sind).
*
* @param request
* der HTTP-request
* @param moduleBaseURL
* base-URL des Moduls
* @param strongName
* a strong name that uniquely identifies a serialization policy file
* @return SerializationPolicy-Objekt
*/
@Override
protected SerializationPolicy doGetSerializationPolicy(HttpServletRequest request, String moduleBaseURL,
String strongName) {
// moduleBaseURL: z.B. "file:///android_asset/www/mvgfahrplan/"
// request.contextPath(): z.B. "/mvg"
if (moduleBaseURL.startsWith("file:")) {
String baseUrl = getBaseUrl(request, extractModuleName(moduleBaseURL));
return super.doGetSerializationPolicy(request, baseUrl, strongName);
} else {
return super.doGetSerializationPolicy(request, moduleBaseURL, strongName);
}
}
/**
* Extrahiert den Modul-Namen aus der module base url.
*
* @param moduleBaseURL
* den Modulnamen.
* @return die Module base URL
*/
public static final String extractModuleName(String moduleBaseURL) {
if (moduleBaseURL == null) {
return null;
} else if (moduleBaseURL.length() == 0) {
return "";
} else {
if (moduleBaseURL.endsWith("/")) {
moduleBaseURL = moduleBaseURL.substring(0, moduleBaseURL.length() - 1);
}
if (moduleBaseURL.lastIndexOf("/") > 0) {
final int lastSlash = moduleBaseURL.lastIndexOf("/");
return moduleBaseURL.substring(lastSlash + 1, moduleBaseURL.length());
}
return moduleBaseURL;
}
}
@Override
public String processCall(String payload) throws SerializationException {
if (isJsonp) {
try {
RPCRequest rpcRequest = RPC.decodeRequest(payload, this.getClass(), this);
onAfterRequestDeserialized(rpcRequest);
String encodedResponse = RPC.invokeAndEncodeResponse(this, rpcRequest.getMethod(),
rpcRequest.getParameters(), rpcRequest.getSerializationPolicy(), rpcRequest.getFlags());
// the responseStr by default is a GWT-RPC string. We'll need to
// turn it into a JSON object, and pad it with the
// callback function.
String responseStr = callbackFunction + "({\"entry\":\"" + encodedResponse.replaceAll("\"", "\\\\\"")
+ "\"});";
return responseStr;
} catch (IncompatibleRemoteServiceException ex) {
log("An IncompatibleRemoteServiceException was thrown while processing this call.", ex);
return RPC.encodeResponseForFailure(null, ex);
}
} else {
return super.processCall(payload);
}
}
}