1

I'm developing a java client/server architecture where a client sends a message to the server using jackson. Exchanged data is defined by the Message class:

public class Message {
    private Header header; //Object that contains only String
    private Object pdu;

    public Message() {
    }

    // Get & Set
    [...]
}

This class can contain any object thanks to the pdu field. For example, a Data object can be instantiated and added as message.

public class Data{
    private String name;
    private String type;

    public Data() {
    }

    // Get & Set
    [...]
}

On the server side, when the message is received, I would like to retrieve the nested object (Data). However, the following exception occurs "com.fasterxml.jackson.databind.node.ObjectNode cannot be cast to Model.Data" when I try to cast the pdu into Data object. How can I perform that for any object.

Here is the server snippet code:

Socket socket = serverSocket.accept();
is = new DataInputStream(socket.getInputStream());
os = new DataOutputStream(socket.getOutputStream());
BufferedReader in = new BufferedReader(new InputStreamReader(is));

ObjectMapper mapper = new ObjectMapper();
Message message = mapper.readValue(in.readLine(), Message.class);

Data pdu = (Data) message.getPdu(); // Exception here

And here the client snippet code:

Message msg = new Message(header, new Data("NAME", "TYPE"));
ObjectMapper mapper = new ObjectMapper();
String jsonStr = mapper.writeValueAsString(msg);
PrintWriter pw = new PrintWriter(os);
pw.println(jsonStr);
pw.flush();

Note: The message sent by the client and received by the server is formatted as follow: Message{header=Header{type='TYPE', senderAddr='ADDR', senderName='NAME'}, pdu={"name":"NAME","type":"TYPE"}}

Steve23
  • 113
  • 4

1 Answers1

2

There is no way to figure out what pdu Java type is just from just {"name":"NAME", "type":"TYPE"} JSON. If pdu can store multiple different object types (currently it's declared as Object) a JSON field has to be used to tell Jackson what is the actual Java type e.g. by using @JsonTypeInfo:

@JsonTypeInfo(use = Id.NAME, include = As.PROPERTY, property = "type")
@JsonSubTypes({
    @JsonSubTypes.Type(value = DataA.class, name = "data-a"),
    @JsonSubTypes.Type(value = DataB.class, name = "data-b")
}) 

Another approach would be to write a custom serializer/deserializer for pdu field as explained here.

Karol Dowbecki
  • 41,216
  • 9
  • 68
  • 101