Spring Webflux - тело запроса веб-клиента с наследованием - PullRequest
0 голосов
/ 11 ноября 2018

В настоящее время я изучаю Spring Webflux, и я пытался выполнить запрос с помощью Spring Webclient (библиотека Reactor) к другому реактивному API Spring Webflux.

Мой код для запроса веб-клиента выглядит следующим образом:

public Mono<Boolean> addDomainEvent(Mono<DomainEvent> domainEvent) throws WebClientResponseException {
    return webclient.post()
            .uri("/addDomainEvent")
            .contentType(MediaType.APPLICATION_JSON)
            .body(domainEvent, DomainEvent.class)
            .exchange()
            .flatMap(result -> {
                log.debug("Response received: ", result.statusCode().value());
                if (result.statusCode().is4xxClientError() || result.statusCode().is5xxServerError() || HttpStatus.INTERNAL_SERVER_ERROR.value() == result.statusCode().value()) {
                    WebClientResponseException webClientResponseException = new WebClientResponseException("Webclient request failed!", result.statusCode().value(), result.statusCode().getReasonPhrase(),
                            result.headers().asHttpHeaders(), null, result.headers().contentType().map(MimeType::getCharset).orElse(StandardCharsets.ISO_8859_1));
                    log.error("Webclient has been failed >> " + result.statusCode().value() + ": " + result.statusCode().getReasonPhrase(), webClientResponseException);
                    return Mono.error(webClientResponseException);
                }
                return Mono.just(true);
            })
            .onErrorResume(err -> Mono.error(err));
}

Класс DomainEvent - это абстрактный класс, который выглядит следующим образом:

@Data
@JsonTypeInfo(
        use = JsonTypeInfo.Id.NAME,
        include = JsonTypeInfo.As.PROPERTY,
        property = "eventType",
        defaultImpl = DomainEventIgnored.class
)
@JsonSubTypes({
        @JsonSubTypes.Type( value = CatalogCreated.class, name = "CatalogCreated" ),
        @JsonSubTypes.Type( value = ProductAdded.class, name ="ProductAdded"),
        @JsonSubTypes.Type( value = ProductAdded.class, name ="ProductRemoved"),
        @JsonSubTypes.Type( value = ProductAdded.class, name ="ProductUpdated"),
})
public abstract class DomainEvent {

    private final UUID catalogUuid;

    @Getter( NONE )
    @JsonIgnore
    private final Instant when;

    DomainEvent(final UUID catalogUuid, final Instant when) {
        this.catalogUuid=catalogUuid;
        this.when=when;
    }

    @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss'Z'", timezone = "UTC")
    @JsonProperty("occurredOn")
    public Instant occurredOn(){
        return when;
    }

    @JsonProperty("eventType")
    public abstract String eventType();
}

И конкретный класс CatalogCreated, который расширяет класс DomainEvent:

@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@JsonPropertyOrder({"eventType", "catalogUuid", "occurredOn", "storeId", "name"})
public class CatalogCreated extends DomainEvent {
    private final Long storeId;
    private final String name;

    public CatalogCreated(
            @JsonProperty("catalogUuid") final UUID catalogUuid,
            @JsonProperty("occurredOn") final Instant when,
            @JsonProperty("storeId") final Long storeId,
            @JsonProperty("name") final String name
    ) {
        super(catalogUuid, when);
        this.storeId=storeId;
        this.name=name;

    }

    @Override
    @JsonIgnore
    public String eventType() {
        return this.getClass().getSimpleName();
    }
}

При выполнении вышеуказанного запроса Webclient с помощью метода addDomainEvent(Mono<DomainEvent> domainEvent) я использую экземпляр CatalogCreated.class в качестве параметра для метода. Однако, похоже, что метод просто вставляет атрибуты класса DomainEvent в тело запроса, а НЕ атрибуты классов DomainEvent + CatalogCreated. Другими словами, атрибуты name и storeId из класса CatalogCreated отсутствуют в теле почтового запроса, фактическое тело запроса просто содержит атрибуты catalogUuid, eventType и occuredOn класса domainEvent.

Похоже, что операторы .body () или .body (BodyInserts.fromPublisher () не распознают, что класс CatalogCreated является расширенным классом DomainEvent (наследование).

Моя цель - написать метод, который может выполнить запрос Webclient со всеми параметрами фактического конкретного класса (CatalogCreated), используя Mono (родительский / абстрактный класс) в качестве параметра в объявлении метода. Как я могу сделать это правильно?

...