I have some rpc service objects on the server layer for which result
are cached to avoid the expensive database access hit. Because these
result objects contain long object graphs (a few number of association
at various depth level..), I also wished to avoid the GWT
serialization process involved at every hit of these cached object
graph. To achieve this, I wanted to store the GWT-serialized version
of my result objects instead of the normal de-serialized graph. The
cache is planned to refresh itself at regular interval...
My first attempt of doing this was to create a custom version of
'RemoteServiceServlet'
and to replicate some of the functionality found in the RPC class.
In particular, in my CustomRemoteServiceServlet the call to :
responsePayload = RPC.encodeResponseForSuccess(serviceMethod, result)
in the method :
public String processCall(String payload)
is avoided since the invoke of the ServiceMethod already return a pre-
encoded version of the result and the need to encode the response is
eliminated.
And, in my cache layer, I make use of
'ServerSerializationStreamWriter' implementation to store an encoded
GWT-serial form of the result object. So far every thing seemed
ok... except my RPC interface must have a result object signature of
type Object. This is needed since the call to the service layer on
server returns a String (GWT-serial encoded) type, whereas my client
code is expecting the original un-serialized form which necessitates a
cast. So only Object type can circumvent this two forms.
Unfortunately, GWT RPC does not allow a service method to have a
return signature of type Object, so I get an error message ("[ERROR]
In order to produce smaller client-side code, 'Object' is not allowed;
consider using a more specific type"), because it requires a more
specific type to produce smaller client-side code....
Has anyone tried to store and cache pre-encoded GWT-serial form of
result Object from RPC call? Are there any solutions to avoid the
serialization process happening at every RPC calls even the ones for
which results are mostly read-only?
Thank you,
Martin
public class MyServiceServlet extends RemoteServiceServlet implements
MyService {
/** One of your service methods. */
public MySerializableResult getSomething(String key) {
return //...do whatever you would normally do to lookup based on
key...;
}
static Map cache = new Hashtable();
/** Override processCall */
public String processCall(String payload) throws
SerializationException {
try {
RPCRequest rpcRequest = RPC.decodeRequest(payload,
this.getClass());
if (rpcRequest.getMethod().getName().equals("getSomething")) {
// Handle cached method
String key = (String) rpcRequest.getParameters()[0]; // access
key
String result = (String) cache.get(key);
if (result == null) {
result = RPC.invokeAndEncodeResponse(this,
rpcRequest.getMethod(), rpcRequest.getParameters());
cache.put(key, result);
}
return result;
} else {
// Handle method normally
return RPC.invokeAndEncodeResponse(this,
rpcRequest.getMethod(), rpcRequest.getParameters());
}
} catch (IncompatibleRemoteServiceException ex) {
return RPC.encodeResponseForFailure(null, ex);
}
}
}
I guess my cache has to be moved into the custom RemoteServiceServlet
similar to what you have done... I was trying to avoid this as my
cache currently sits at the Service layer and is handled by Spring
which does some depencency injection into it... but I don't know if
I'll be able to resolve the issue I raised with my approach.
Martin
You might try posting in http://groups.google.com/group/gwt-sl and see
if they have any thoughts on this subject.
Another option might be to write a filter and map it to your services
which can be cachable.
1. Filter intercepts request
2. Deserialize parameters.
3. Check cache. Equal request exists use its result. Your object would
need to have its equals/hashcode implemented etc.
4a. Not in cache let filter continue. Capture its output.
4b. Create a new entry in the cache with the object deserailized in
step 2 and store the captured object from step 4a.
4c. Let the filter return.
On Aug 9, 11:36 am, Nathan Williams <nlwil...@gmail.com> wrote:
> If you're using GWT-SL, it seems like you could hack into GWTHandler
> and GWTRPCServiceExporter to support injection/use of a cache bean.
>
> You might try posting inhttp://groups.google.com/group/gwt-sland see
As of now, what I ended up doing was to create a custom
'GWTSpringController' (available in GWT-SL) managed by Spring
container so all dependencies are injected (although it inherits the
RemoteServiceServlet..) and it intercepts the RPC request in a custom
'processCall' similar to what Nathan had suggested.
Thank you,
Martin