concrete data type (pojo) of the data parameter in signature of channel message handler

29 views
Skip to first unread message

Bao

unread,
Jan 14, 2012, 10:33:42 AM1/14/12
to cometd-users
Hi,

I would like to use the following signature for my channel message
handler method
myMethod(ServerSession from,Object data)

The javadoc of the "addService" method says:
"The data parameter can be typed if the type of the data object
published by the client is known (typically Map)"

Is the "data" parameter *always* a java.util.Map? Is it possible to
have the json string sent by the client (in my case, a browser js)
automatically converted to my POJO. In another word, I want to replace
"Object data" by "MyPojoClass data". If it is possible, how can I make
it?

Below is the example of what I mean:

addService("/service/hello", "sayHello");

public Object sayHello(ServerSession newRemoteClient, GreetingsDto
greetings) {
...
}

public class GreetingsDto {
private String sender;
private String message;
// getters/setters
....
}

Thanks,
Bao.

Simone Bordet

unread,
Jan 18, 2012, 11:39:56 AM1/18/12
to cometd...@googlegroups.com
Hi,

Yes that's possible, however, to my knowledge, only with Jetty's JSON library.

Here is a test that shows how you should do it:
https://github.com/cometd/cometd/blob/master/cometd-java/cometd-java-server/src/test/java/org/cometd/server/ServiceWithCustomDataClassTest.java

The key things are:
1. Create and use a JettyJSONContextServer subclass, so that you can
call getJSON() on it (lines 35 and 121)
2. Add a JSON.Convertor to the JSON object you got on step 1 (line 48)
3. In your JavaScript, add the "class" field in the data object,
containing the class that you want to deserialize to in the server.
(line 67).

Alternative to 2, you can have your DTO class implement JSON.Convertible.

I could not do this with Jackson.

Simon
--
http://cometd.org
http://intalio.com
http://bordet.blogspot.com
----
Finally, no matter how good the architecture and design are,
to deliver bug-free software with optimal performance and reliability,
the implementation technique must be flawless.   Victoria Livschitz

Ho.Tri.Bao

unread,
Jan 19, 2012, 9:45:02 AM1/19/12
to cometd...@googlegroups.com
I followed you and it worked. For jackson, I gave up as making custom deserializer is complicated for me.

And finally, I decided to implement another approach which help me be independent from JSON libraries (either jetty json or jackson):

1. In json string sent by javascript, like jetty-json approach, I need to include a "class" property.
2. Subclass the BayeuxServerImpl and override method doPublish(ServerSessionImpl from, ServerChannelImpl to, Mutable mutable)
3. Get the data map out of the mutable message, if it contains "class" entry then I call corresponding "converter" to convert to the concrete bean.
4. Replace the value of "data" entry in the Mutable message by the bean created at previous step.

Thanks.

Simone Bordet

unread,
Jan 19, 2012, 9:54:57 AM1/19/12
to cometd...@googlegroups.com
Hi,

Thanks for sharing !

You do not need to subclass BayeuxServerImpl. Just do 3. in a message
listener on server.
You can modify the message inside message listeners, and that's fully
portable because it's based on the API, not the implementation.

Reply all
Reply to author
Forward
0 new messages