Home > Software design >  SpringBoot @RequestBody validation of abstract class
SpringBoot @RequestBody validation of abstract class

Time:04-12

I am trying to simulate the oneOf construct from OpenAPI spec in my spring-boot application. I have an abstract class Apple

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "color")
@JsonSubTypes({
        @JsonSubTypes.Type(value = RedApple.class, name = "RED"),
        @JsonSubTypes.Type(value = GreenApple.class, name = "GREEN")
})
public abstract class Apple {

    @NotNull
    private Color color;

    public Color getColor() {
        return color;
    }

    public void setColor(Color color) {
        this.color = color;
    }

    public enum Color {
        RED, GREEN
    }
}

and two subclasses

public class RedApple extends Apple {

}

public class GreenApple extends Apple {

}

Also here is my rest controller

@RestController
@RequestMapping("/apples")
public class AppleController {

    @PostMapping
    public ResponseEntity<Void> createApple(@Valid @RequestBody Apple apple) {
        return ResponseEntity.created(URI.create("/foo")).build();
    }
}

The problem is that @Valid does not validate the enum field correctly. Even if I send {"color": "RED"} as a body, the validation fails with a message saying that color must not be null

When I do the exact same thing with a non-abstract class and without JsonSubTypes & JsonTypeInfo annotations everything works like a charm. What am I missing here?

Thanks

CodePudding user response:

The object you are trying to create is of the abstract class, as we know Abstract classes cannot be instantiated the whole idea of abstraction is to refrain from access of that class itself, instead if you pass the class object which has implemented the abstract class would solve your issue

eg to pass RED

 public ResponseEntity<Void> createApple(@Valid @RequestBody RedApple apple) {
        return ResponseEntity.created(URI.create("/foo")).build();
    }

CodePudding user response:

adding visible = true as parameter to the JsonTypeInfo solved the issue @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, visible = true, property = "color")

  • Related