SpringBoot OpenAPI 定义多态性与anyOf 和 discriminatorProperty

问题描述 投票:0回答:1

当 POST 包含多态实体的对象映射的

@RequestBody
时,如何在 SpringBoot openapi 类型定义中定义实体继承?

设置

anyOf = { PolarParrot.class, NorwegianParrot.class}, discriminatorProperty = "parrotType"
以便键入提示必须使用哪个具体
Parrot
实例来解析
RequestBody
是否足够?

import java.lang.Override;
import java.net.URI;
import java.util.Map;

import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.Valid;

@RestController
public class PolyParrot {
    @PostMapping(value = {"/create"}, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<?> create(@Valid @RequestBody Flock flock) {
        return ResponseEntity.created(URI.create("/flock/42")).build();
    }
}

@Schema(additionalProperties = Schema.AdditionalPropertiesValue.TRUE)
class Flock {
    @Schema
    Map<String, Parrot> birds;

    public Map<String, Parrot> getBirds() {
        return birds;
    }

    public void setBirds(Map<String, Parrot> birds) {
        this.birds = birds;
    }
}

@Schema(anyOf = {
        PolarParrot.class,
        NorwegianParrot.class,
}, discriminatorProperty = "parrotType")
interface Parrot {
    String getParrotType();
    String getPlumage();
}

@Schema()
class PolarParrot implements Parrot {
    @Schema(requiredMode = Schema.RequiredMode.REQUIRED, defaultValue = "polar", example = "polar")
    String parrotType;

    @Override
    public String getParrotType() {
        return parrotType;
    }

    @Override
    public String getPlumage() {
        return "red";
    }
}

@Schema()
class NorwegianParrot implements Parrot {
    @Schema(requiredMode = Schema.RequiredMode.REQUIRED, defaultValue = "norwegian", example = "norwegian")
    String parrotType;

    @Override
    public String getParrotType() {
        return parrotType;
    }

    @Override
    public String getPlumage() {
        return "blue";
    }
}

根据文档和示例,似乎

anyOf
+
discriminatorProperty
应该足够了,但是,当 POST 有效负载而不是反序列化的
flock
对象时,它会抛出:

com.fasterxml.jackson.databind.exc.InvalidDefinitionException: 
Cannot construct instance of `Parrot` 
(no Creators, like default constructor, exist): 
abstract types either need to be mapped to concrete types, 
have custom deserializer, or contain additional type information

Parrot
还没有包含足够的“附加类型信息”吗?

我在这里错过了哪个重要部分?

java spring spring-boot swagger openapi
1个回答
0
投票

com.fasterxml.jackson.databind.exc.InvalidDefinitionException: 无法构造

Parrot
的实例 (不存在像默认构造函数这样的创建者): 抽象类型要么需要映射到具体类型, 有自定义解串器,或包含附加类型信息

该错误表明,在反序列化期间,无法参考抽象类型解析有效负载中的子类型。

用此注释 Parrot 接口,并根据相应的子类在有效负载中包含关键“类型”,如下所示:

© www.soinside.com 2019 - 2024. All rights reserved.