Json deserialize to specific Java class subtype without sending @class or @type from frontend

27 views Asked by At

I'm a junior and am working on a chat app, Angular for frontend and Spring boot for Backend, and an external library called ChatServer. In my BFF i'm using the models from the ChatServer. One of those models is called ChatMessage:

@Getter
@NoArgsConstructor
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS)
public class ChatMessage extends ChatPackage {
    private static final long serialVersionUID = 0L;
    private String body;
    private Map<String, Serializable> values;

    public ChatMessage(ChatRoom room, ChatUser from, Date timetamp, String body) {
        this(room,from,timetamp, body, new HashMap<>());
    }

    public ChatMessage(ChatRoom room, ChatUser from, Date timestamp, String body,
            Map<String, Serializable> values) {
        super(room, from, timestamp);
        this.body = body;
        this.values = values;
    }
}

Due to the constructor structure in this library class, from my Angular frontend I'm sending a ChatMessageDTO:

export interface ChatMessageDTO {
  room: ChatRoom;
  from: ChatUser;
  timestamp: Date;
  message: ChatMessage;
}

and in my BFF I have a similar DTO for incoming requests:

@RequiredArgsConstructor
@Data
public class ChatMessageDTO {
  private ChatRoom room;
  private ChatUser from;
  private Date timestamp;
  private ChatMessage message;

}

But i get this error in my BFF:

10:49:14.705 [http-nio-8090-exec-4] DEBUG o.s.web.method.HandlerMethod - Could not resolve parameter [0] in public org.springframework.http.ResponseEntity<java.lang.Void> ChatController.sendMessage(chat.model.ChatMessageDTO): JSON parse error: Could not resolve subtype of [simple type, class chat.data.ChatMessage]: missing type id property '@class' (for POJO property 'message')

I've read this, as well as many other sources - and my understanding is that the only way for this to work is to send @class from the frontend. I've tried it and it works, but it looks like an ugly fix, since my model will look like:

export interface ChatMessageDTO {
  room: ChatRoom;
  from: ChatUser;
  timestamp: Date;
  message: ChatMessage;
 '@class': 'classpath.etc.etc'
}

I have not yet found a better and cleaner way for this to work. Is there really no better way? Do i need to hardcode this parameter in my frontend?

Thank you

0

There are 0 answers