Use encode with an Object value where feasible
Closes gh-22782
This commit is contained in:
@@ -33,7 +33,6 @@ import org.springframework.core.ResolvableType;
|
||||
import org.springframework.core.codec.Encoder;
|
||||
import org.springframework.core.io.buffer.DataBuffer;
|
||||
import org.springframework.core.io.buffer.DataBufferFactory;
|
||||
import org.springframework.core.io.buffer.DataBufferUtils;
|
||||
import org.springframework.core.io.buffer.DefaultDataBufferFactory;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.messaging.Message;
|
||||
@@ -148,7 +147,7 @@ public abstract class AbstractEncoderMethodReturnValueHandler implements Handler
|
||||
|
||||
Encoder<?> encoder = getEncoder(elementType, mimeType);
|
||||
|
||||
return Flux.from((Publisher) publisher).concatMap(value ->
|
||||
return Flux.from((Publisher) publisher).map(value ->
|
||||
encodeValue(value, elementType, encoder, bufferFactory, mimeType, hints));
|
||||
}
|
||||
|
||||
@@ -176,7 +175,7 @@ public abstract class AbstractEncoderMethodReturnValueHandler implements Handler
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private <T> Mono<DataBuffer> encodeValue(
|
||||
private <T> DataBuffer encodeValue(
|
||||
Object element, ResolvableType elementType, @Nullable Encoder<T> encoder,
|
||||
DataBufferFactory bufferFactory, @Nullable MimeType mimeType,
|
||||
@Nullable Map<String, Object> hints) {
|
||||
@@ -184,13 +183,11 @@ public abstract class AbstractEncoderMethodReturnValueHandler implements Handler
|
||||
if (encoder == null) {
|
||||
encoder = getEncoder(ResolvableType.forInstance(element), mimeType);
|
||||
if (encoder == null) {
|
||||
return Mono.error(new MessagingException(
|
||||
"No encoder for " + elementType + ", current value type is " + element.getClass()));
|
||||
throw new MessagingException(
|
||||
"No encoder for " + elementType + ", current value type is " + element.getClass());
|
||||
}
|
||||
}
|
||||
Mono<T> mono = Mono.just((T) element);
|
||||
Flux<DataBuffer> dataBuffers = encoder.encode(mono, bufferFactory, elementType, mimeType, hints);
|
||||
return DataBufferUtils.join(dataBuffers);
|
||||
return encoder.encodeValue((T) element, bufferFactory, elementType, mimeType, hints);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -32,7 +32,6 @@ import org.springframework.core.ResolvableType;
|
||||
import org.springframework.core.codec.Decoder;
|
||||
import org.springframework.core.codec.Encoder;
|
||||
import org.springframework.core.io.buffer.DataBuffer;
|
||||
import org.springframework.core.io.buffer.DataBufferUtils;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.MimeType;
|
||||
@@ -124,8 +123,10 @@ final class DefaultRSocketRequester implements RSocketRequester {
|
||||
publisher = adapter.toPublisher(input);
|
||||
}
|
||||
else {
|
||||
Mono<Payload> payloadMono = encodeValue(input, ResolvableType.forInstance(input), null)
|
||||
Mono<Payload> payloadMono = Mono
|
||||
.fromCallable(() -> encodeValue(input, ResolvableType.forInstance(input), null))
|
||||
.map(this::firstPayload)
|
||||
.doOnDiscard(Payload.class, Payload::release)
|
||||
.switchIfEmpty(emptyPayload());
|
||||
return new DefaultResponseSpec(payloadMono);
|
||||
}
|
||||
@@ -140,36 +141,36 @@ final class DefaultRSocketRequester implements RSocketRequester {
|
||||
|
||||
if (adapter != null && !adapter.isMultiValue()) {
|
||||
Mono<Payload> payloadMono = Mono.from(publisher)
|
||||
.flatMap(value -> encodeValue(value, dataType, encoder))
|
||||
.map(value -> encodeValue(value, dataType, encoder))
|
||||
.map(this::firstPayload)
|
||||
.switchIfEmpty(emptyPayload());
|
||||
return new DefaultResponseSpec(payloadMono);
|
||||
}
|
||||
|
||||
Flux<Payload> payloadFlux = Flux.from(publisher)
|
||||
.concatMap(value -> encodeValue(value, dataType, encoder))
|
||||
.map(value -> encodeValue(value, dataType, encoder))
|
||||
.switchOnFirst((signal, inner) -> {
|
||||
DataBuffer data = signal.get();
|
||||
if (data != null) {
|
||||
return Flux.concat(
|
||||
Mono.just(firstPayload(data)),
|
||||
inner.skip(1).map(PayloadUtils::createPayload));
|
||||
return Mono.fromCallable(() -> firstPayload(data))
|
||||
.concatWith(inner.skip(1).map(PayloadUtils::createPayload));
|
||||
}
|
||||
else {
|
||||
return inner.map(PayloadUtils::createPayload);
|
||||
}
|
||||
})
|
||||
.doOnDiscard(Payload.class, Payload::release)
|
||||
.switchIfEmpty(emptyPayload());
|
||||
return new DefaultResponseSpec(payloadFlux);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private <T> Mono<DataBuffer> encodeValue(T value, ResolvableType valueType, @Nullable Encoder<?> encoder) {
|
||||
private <T> DataBuffer encodeValue(T value, ResolvableType valueType, @Nullable Encoder<?> encoder) {
|
||||
if (encoder == null) {
|
||||
encoder = strategies.encoder(ResolvableType.forInstance(value), dataMimeType);
|
||||
}
|
||||
return DataBufferUtils.join(((Encoder<T>) encoder).encode(
|
||||
Mono.just(value), strategies.dataBufferFactory(), valueType, dataMimeType, EMPTY_HINTS));
|
||||
return ((Encoder<T>) encoder).encodeValue(
|
||||
value, strategies.dataBufferFactory(), valueType, dataMimeType, EMPTY_HINTS);
|
||||
}
|
||||
|
||||
private Payload firstPayload(DataBuffer data) {
|
||||
|
||||
@@ -81,7 +81,7 @@ public class MessageMappingMessageHandlerTests {
|
||||
@Test
|
||||
public void handleFluxString() {
|
||||
MessageMappingMessageHandler messsageHandler = initMesssageHandler();
|
||||
messsageHandler.handleMessage(message("fluxString", "abc\ndef\nghi")).block(Duration.ofSeconds(5));
|
||||
messsageHandler.handleMessage(message("fluxString", "abc", "def", "ghi")).block(Duration.ofSeconds(5));
|
||||
verifyOutputContent(Arrays.asList("abc::response", "def::response", "ghi::response"));
|
||||
}
|
||||
|
||||
|
||||
@@ -129,9 +129,10 @@ public class PayloadMethodArgumentResolverTests {
|
||||
|
||||
@Test
|
||||
public void validateStringMono() {
|
||||
TestValidator validator = new TestValidator();
|
||||
ResolvableType type = ResolvableType.forClassWithGenerics(Mono.class, String.class);
|
||||
MethodParameter param = this.testMethod.arg(type);
|
||||
Mono<Object> mono = resolveValue(param, Mono.just(toDataBuffer("12345")), new TestValidator());
|
||||
Mono<Object> mono = resolveValue(param, Mono.just(toDataBuffer("12345")), validator);
|
||||
|
||||
StepVerifier.create(mono).expectNextCount(0)
|
||||
.expectError(MethodArgumentNotValidException.class).verify();
|
||||
@@ -139,9 +140,11 @@ public class PayloadMethodArgumentResolverTests {
|
||||
|
||||
@Test
|
||||
public void validateStringFlux() {
|
||||
TestValidator validator = new TestValidator();
|
||||
ResolvableType type = ResolvableType.forClassWithGenerics(Flux.class, String.class);
|
||||
MethodParameter param = this.testMethod.arg(type);
|
||||
Flux<Object> flux = resolveValue(param, Mono.just(toDataBuffer("12345678\n12345")), new TestValidator());
|
||||
Flux<DataBuffer> content = Flux.just(toDataBuffer("12345678"), toDataBuffer("12345"));
|
||||
Flux<Object> flux = resolveValue(param, content, validator);
|
||||
|
||||
StepVerifier.create(flux)
|
||||
.expectNext("12345678")
|
||||
|
||||
Reference in New Issue
Block a user