I am currently working on a thin-client application, where the communication happens through JSON-serialized message objects. Server serializes the message, sends it through a socket, client receives and deserializes. Answers happen in the same way.
First, let's assume the message class are defined both on server and client.
Problem is that Gson::fromJson
function needs a .class/type object for deserializing via introspection (understandably), but in my application, multiple type of objects can be received without knowing the .class in advance.
My idea was to create a message wrapper like this:
class MessageWrapper {
public class MessageWrapper(Object message, MessageType type) {
this.message = message;
this.type = type;
}
// getters...
public enum MesssageType {
PLACEMENT,
UPDATE,
// ...
}
private final Object message;
private final MessageType type;
}
Or even go further by determining type
param with introspection. This solution is great for serializing (I repeat, that is not a problem), but while deserializing I would get the message type and loose the message itself, at least if I don't parse it twice. Specializing MessageWrapper through Java "templating" mechanism brings us back to the original problem (I would have multiple classes to choose from).
Another idea, was to send a token to identify the message, before the JSON string, like:
Placement={"foo": 2, "bar": "baz"}
Then read the token to determine the .class type. This could work, but there is still a problem: how would I return the value from my receive
function? Of course I could do:
public Object receive(Reader stream) {}
And force the user to do a downcast, but I'd rather avoid it.
EDIT: this is because the client has a reactor-like structure: it runs in a loop and dispatches messages to appropriate handlers.