0

I'm picking up some code that someone else wrote and I'm having a hard time understanding how to access the child class.

Parent Class:

package blah.blah.blah;

import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.JsonSubTypes;

import java.io.Serializable;
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXTERNAL_PROPERTY, property = "type")
@JsonSubTypes({
    @JsonSubTypes.Type(value = EmailMessage.class, name = "Email"),
    @JsonSubTypes.Type(value = SMSMessage.class, name = "SMS")
})    
public class Message implements Serializable {

   private static final long serialVersionUID = 1L;

   private String messageBody;

   public String getMessageBody() {
      return messageBody;
   }
   public void setMessageBody(String messageBody) {
      this.messageBody = messageBody;
   }
}

Child Class:

package blah.blah.blah;

public class EmailMessage extends Message {
   private String subject;

   public String getSubject() {
       return subject;
   }
   public void setSubject(String subject) {
       this.subject = subject;
   }
}

Child Class:

package blah.blah.blah;

public class SMSMessage extends Message {
}

I have an instance of Message that was mapped from a JSON message but I cannot figure out how to access the 'Type' field and how to access the 'Subject' field (if it's an email).

JSON:

"messageList": [{
    "type": "Email",
    "messageBody": "Email body",
    "subject": "Email subject"
}, {
    "type": "SMS",
    "messageBody": "SMS body"
}]

What I've tried:

Message incomingMessage = messageList.getMessageList().get(0);
log.info("Message Body: " + incomingMessage.getMessageBody());
Kyle Bridenstine
  • 6,055
  • 11
  • 62
  • 100
  • that usually means in code you have to do sth like `if (message instanceof EmailMessage) { .. cast .. }` – zapl Jun 10 '16 at 14:27
  • You have an instance of Message or a List of messages? In any case, what have you tried? – OneCricketeer Jun 10 '16 at 14:27
  • I just updated it with what I've tried. There's a list of Messages and I'm getting the first one to try and see if I can get the type. – Kyle Bridenstine Jun 10 '16 at 14:28
  • And you shouldn't need access to the type field (because it isn't exposed in the model). You need to use `instanceof` – OneCricketeer Jun 10 '16 at 14:29
  • @zapl Ok that makes sense. I just thought maybe there would be a way to say like message.type(). – Kyle Bridenstine Jun 10 '16 at 14:29
  • Not with `EXTERNAL_PROPERTY` - but you can make it an explicit property of the `Message` class, then use it in a switch on the String. But that's not much better than using `instanceof` so I wouldn't care to change that. – zapl Jun 10 '16 at 14:47

1 Answers1

1

Thanks @cricket_007 and @zapl for the answer in the comments. Feel free to write this answer and I'll accept yours. But here is what I have now that is working.

    for (Message incomingMessage : messageInitRequest.getMessageList()) {

        if (incomingMessage instanceof EmailMessage) {

            EmailMessage emailMessage = (EmailMessage) incomingMessage;

            System.out.println("Type: Email");
            System.out.println(emailMessage.getMessageBody());
            System.out.println(emailMessage.getSubject());

        } else if (incomingMessage instanceof SMSMessage) {

            SMSMessage smsMessage = (SMSMessage) incomingMessage;

            System.out.println("Type: SMS");
            System.out.println(smsMessage.getMessageBody());
        }

    }
Kyle Bridenstine
  • 6,055
  • 11
  • 62
  • 100