'A way of polymorphic HTTP Requests using Postman?
I'm trying to make use of polymorphism with Java. I build a simple CRUD app with Spring Boot and i wanted to test it with Postman...
Problem is, i got next exception:
WARN 4576 --- [nio-8080-exec-2] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Could not resolve subtype of [simple type, class com.shoppingprojectwithhibernate.PromotionsModule.Domain.PromotionSeason]: missing type id property 'promotionSeason' (for POJO property 'promotionSeason'); nested exception is com.fasterxml.jackson.databind.exc.InvalidTypeIdException: Could not resolve subtype of [simple type, class com.balabasciuc.shoppingprojectwithhibernate.PromotionsModule.Domain.PromotionSeason]: missing type id property 'promotionSeason' (for POJO property 'promotionSeason')<EOL> at [Source: (org.springframework.util.StreamUtils$NonClosingInputStream); line: 3, column: 25] (through reference chain: com.shoppingprojectwithhibernate.PromotionsModule.Domain.Promotion["promotionSeason"])]
when i'm trying to make a POST request to an endpoint, that endpoint return an interface, and in runtime can be any subtype, i scrolled here for solutions, i used jackson used from others solutions, but none worked so far for me, can you give me a hint, please?
my interface:
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "promotionSeason")
@JsonSubTypes(
{
@JsonSubTypes.Type(value = PromotionChristmasSeason.class, name = "christmasPromotion"),
@JsonSubTypes.Type(value = PromotionEasterSeason.class, name = "easterPromotion"),
@JsonSubTypes.Type(value = NoPromotionForYouThisTimeMUHAHA.class, name = "noPromotion")
})
public interface PromotionSeason {
String isSeason();
Interface subtype:
@JsonTypeName(value = "noPromotion")
public class NoPromotionForYouThisTimeMUHAHA implements PromotionSeason {
Promotion class Entity constructor:
public Promotion(int numberOfProductsAtPromotion, PromotionSeason promotionSeason) {
this.numberOfProductsAtPromotion = numberOfProductsAtPromotion;
this.promotionSeason = promotionSeason;
}
Rest Controller class
@RestController
@RequestMapping(value = "/promotions")
public class PromotionController {
@PostMapping(value = "/createPromotion")
public ResponseEntity<String> createPromotion(@RequestBody Promotion promotion)
{
promotionService.createPromotion(promotion);
return ResponseEntity.status(HttpStatus.CREATED)
.body("Done");
}
Postman request:
{
"numberOfProductsAtPromotion" : 20,
"promotionSeason" : "noPromotion"
}
Postman response:
{
"timestamp": "2022-05-04T18:58:06.873+00:00",
"status": 400,
"error": "Bad Request",
"path": "/promotions/createPromotion"
}
Spring Response:
2022-05-04 21:19:44.374 WARN 4576 --- [nio-8080-exec-2] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Could not resolve subtype of [simple type, class com.shoppingprojectwithhibernate.PromotionsModule.Domain.PromotionSeason]: missing type id property 'promotionSeason' (for POJO property 'promotionSeason'); nested exception is com.fasterxml.jackson.databind.exc.InvalidTypeIdException: Could not resolve subtype of [simple type, class com.balabasciuc.shoppingprojectwithhibernate.PromotionsModule.Domain.PromotionSeason]: missing type id property 'promotionSeason' (for POJO property 'promotionSeason')<EOL> at [Source: (org.springframework.util.StreamUtils$NonClosingInputStream); line: 3, column: 25] (through reference chain: com.shoppingprojectwithhibernate.PromotionsModule.Domain.Promotion["promotionSeason"])]
Solution 1:[1]
It was my bad Post request all along, instead of:
Postman request:
{
"numberOfProductsAtPromotion" : 20,
"promotionSeason" : "noPromotion" }
it should be:
{
"numberOfProductsAtPromotion" : 20,
"promotionSeason" : { // "promotionSeason" is class instance var from Promotion Entity class
"promotionSeason" : "noPromotion" // "promotionSeason" is defined on interface level: `@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "promotionSeason")`
//"noPromotion" is defined on interface and subtype levels
//any more subtype(subclass) variables to init if any
}
check this: https://www.youtube.com/watch?v=IlLC3Yetil0
Solution 2:[2]
Do you have any contructor in NoPromotionForYouThisTimeMUHAHA? if you have 'Type' in all implementations, you can change interfaceto abstract class and add variable here.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | MyProblems |
| Solution 2 | Wolski |
