В настоящее время я изучаю 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 (родительский / абстрактный класс) в качестве параметра в объявлении метода. Как я могу сделать это правильно?