Cannot use field (interface) in request body in spring boot for polymorphism support

Viewed 20

I plan that my spring project can handle multiple request forms like:

{
   "notification": "order_creation_notification",
   "data": {
       "date": "22 Jan 2022"
   }
}

and

{
   "notification": "login_notification",
   "data": {
       "email": "johndoe@email.com",
       "at": "LA, USA"
   }
}

So, i create my controller and request body like this:

  • Here are my controller:
@PostMapping(value="/")
public void createNotification(@RequestBody NotificationRequest request) {
            ...
    }  
  • and here are my request classes:
@JsonTypeInfo(use = Id.DEDUCTION)
@JsonSubTypes({
    @Type(OrderCreationNotification.class),
    @Type(LoginNotification.class)
})
public interface IData {
    
}
@AllArgsConstructor
@Getter
@Setter
public class OrderCreationNotification implements IData {
    private Date date;
}
@AllArgsConstructor
@Getter
@Setter
public class LoginNotification implements IData {
    private String email;
    private String at;
}
@AllArgsConstructor
@Getter
@Setter
public class NotificationRequest {
    private String notification;
    private IData data;
}

But, when i try to do POST using this json body:

{
   "notification": "login_notification",
   "data": {
       "email": "johndoe@email.com",
       "at": "LA, USA"
   }
}

i get an error which says:

JSON parse error: Cannot construct instance of `LoginNotification` (although at least one Creator exists): cannot deserialize from Object value (no delegate- or property-based Creator); nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of `LoginNotification` (although at least one Creator exists): cannot deserialize from Object value (no delegate- or property-based Creator)\n at [Source: (org.springframework.util.StreamUtils$NonClosingInputStream); line: 8, column: 13] (through reference chain: NotificationRequest[\"data\"])
1 Answers

Your code is almost correct.

Just don't use Date date in OrderCreationNotification.

use field String date, and convert String to Date in custom way.

Related