Home > database >  A way of polymorphic HTTP Requests using Postman?
A way of polymorphic HTTP Requests using Postman?

Time:05-08

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"])]

CodePudding user response:

Do you have any contructor in NoPromotionForYouThisTimeMUHAHA? if you have 'Type' in all implementations, you can change interfaceto abstract class and add variable here.

CodePudding user response:

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

  • Related