mirror of
https://github.com/spring-projects/spring-framework.git
synced 2026-09-18 00:49:02 +00:00
Fix handling of ServerSentEvent with Jackson encoder
This commit fixes ServerSentEvent handling with Jackson encoder when no Accept header is specified. It also moves the String checks to the JSON codec level, as they do not make sense for binary formats. Closes gh-35872
This commit is contained in:
@@ -102,14 +102,7 @@ public abstract class AbstractJacksonDecoder<T extends ObjectMapper> extends Jac
|
||||
|
||||
@Override
|
||||
public boolean canDecode(ResolvableType elementType, @Nullable MimeType mimeType) {
|
||||
if (!supportsMimeType(mimeType)) {
|
||||
return false;
|
||||
}
|
||||
T mapper = selectMapper(elementType, mimeType);
|
||||
if (mapper == null) {
|
||||
return false;
|
||||
}
|
||||
return !CharSequence.class.isAssignableFrom(elementType.toClass());
|
||||
return supportsMimeType(mimeType) && (selectMapper(elementType, mimeType) != null);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -126,14 +126,11 @@ public abstract class AbstractJacksonEncoder<T extends ObjectMapper> extends Jac
|
||||
if (this.mapperRegistrations != null && selectMapper(elementType, mimeType) == null) {
|
||||
return false;
|
||||
}
|
||||
Class<?> clazz = elementType.resolve();
|
||||
if (clazz == null) {
|
||||
return true;
|
||||
}
|
||||
if (MappingJacksonValue.class.isAssignableFrom(clazz)) {
|
||||
Class<?> elementClass = elementType.toClass();
|
||||
if (MappingJacksonValue.class.isAssignableFrom(elementClass)) {
|
||||
throw new UnsupportedOperationException("MappingJacksonValue is not supported, use hints instead");
|
||||
}
|
||||
return !String.class.isAssignableFrom(clazz);
|
||||
return !ServerSentEvent.class.isAssignableFrom(elementClass);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -104,6 +104,11 @@ public class JacksonJsonDecoder extends AbstractJacksonDecoder<JsonMapper> {
|
||||
super(mapper, mimeTypes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canDecode(ResolvableType elementType, @Nullable MimeType mimeType) {
|
||||
return super.canDecode(elementType, mimeType) && !CharSequence.class.isAssignableFrom(elementType.toClass());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Flux<DataBuffer> processInput(Publisher<DataBuffer> input, ResolvableType elementType,
|
||||
@Nullable MimeType mimeType, @Nullable Map<String, Object> hints) {
|
||||
|
||||
@@ -121,6 +121,11 @@ public class JacksonJsonEncoder extends AbstractJacksonEncoder<JsonMapper> {
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean canEncode(ResolvableType elementType, @Nullable MimeType mimeType) {
|
||||
return super.canEncode(elementType, mimeType) && !String.class.isAssignableFrom(elementType.toClass());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<MimeType> getMediaTypesForProblemDetail() {
|
||||
return problemDetailMimeTypes;
|
||||
|
||||
+1
-1
@@ -57,7 +57,7 @@ class JacksonCborDecoderTests extends AbstractDecoderTests<JacksonCborDecoder> {
|
||||
assertThat(decoder.canDecode(ResolvableType.forClass(Pojo.class), MediaType.APPLICATION_CBOR)).isTrue();
|
||||
assertThat(decoder.canDecode(ResolvableType.forClass(Pojo.class), null)).isTrue();
|
||||
|
||||
assertThat(decoder.canDecode(ResolvableType.forClass(String.class), null)).isFalse();
|
||||
assertThat(decoder.canDecode(ResolvableType.forClass(String.class), null)).isTrue();
|
||||
assertThat(decoder.canDecode(ResolvableType.forClass(Pojo.class), APPLICATION_JSON)).isFalse();
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -59,6 +59,7 @@ class JacksonCborEncoderTests extends AbstractLeakCheckingTests {
|
||||
ResolvableType pojoType = ResolvableType.forClass(Pojo.class);
|
||||
assertThat(this.encoder.canEncode(pojoType, MediaType.APPLICATION_CBOR)).isTrue();
|
||||
assertThat(this.encoder.canEncode(pojoType, null)).isTrue();
|
||||
assertThat(this.encoder.canEncode(ResolvableType.forClass(String.class), null)).isTrue();
|
||||
|
||||
// SPR-15464
|
||||
assertThat(this.encoder.canEncode(ResolvableType.NONE, null)).isTrue();
|
||||
@@ -66,7 +67,6 @@ class JacksonCborEncoderTests extends AbstractLeakCheckingTests {
|
||||
|
||||
@Test
|
||||
void canNotEncode() {
|
||||
assertThat(this.encoder.canEncode(ResolvableType.forClass(String.class), null)).isFalse();
|
||||
assertThat(this.encoder.canEncode(ResolvableType.forClass(Pojo.class), APPLICATION_XML)).isFalse();
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -62,7 +62,7 @@ class JacksonSmileDecoderTests extends AbstractDecoderTests<JacksonSmileDecoder>
|
||||
assertThat(decoder.canDecode(ResolvableType.forClass(Pojo.class), STREAM_SMILE_MIME_TYPE)).isTrue();
|
||||
assertThat(decoder.canDecode(ResolvableType.forClass(Pojo.class), null)).isTrue();
|
||||
|
||||
assertThat(decoder.canDecode(ResolvableType.forClass(String.class), null)).isFalse();
|
||||
assertThat(decoder.canDecode(ResolvableType.forClass(String.class), null)).isTrue();
|
||||
assertThat(decoder.canDecode(ResolvableType.forClass(Pojo.class), APPLICATION_JSON)).isFalse();
|
||||
}
|
||||
|
||||
|
||||
+2
-1
@@ -65,6 +65,7 @@ class JacksonSmileEncoderTests extends AbstractEncoderTests<JacksonSmileEncoder>
|
||||
assertThat(this.encoder.canEncode(pojoType, SMILE_MIME_TYPE)).isTrue();
|
||||
assertThat(this.encoder.canEncode(pojoType, STREAM_SMILE_MIME_TYPE)).isTrue();
|
||||
assertThat(this.encoder.canEncode(pojoType, null)).isTrue();
|
||||
assertThat(this.encoder.canEncode(ResolvableType.forClass(String.class), null)).isTrue();
|
||||
|
||||
// SPR-15464
|
||||
assertThat(this.encoder.canEncode(ResolvableType.NONE, null)).isTrue();
|
||||
@@ -72,7 +73,7 @@ class JacksonSmileEncoderTests extends AbstractEncoderTests<JacksonSmileEncoder>
|
||||
|
||||
@Test
|
||||
void cannotEncode() {
|
||||
assertThat(this.encoder.canEncode(ResolvableType.forClass(String.class), null)).isFalse();
|
||||
|
||||
assertThat(this.encoder.canEncode(ResolvableType.forClass(Pojo.class), APPLICATION_XML)).isFalse();
|
||||
}
|
||||
|
||||
|
||||
-1
@@ -146,7 +146,6 @@ class SseIntegrationTests extends AbstractHttpHandlerIntegrationTests {
|
||||
|
||||
Flux<ServerSentEvent<Person>> result = this.webClient.get()
|
||||
.uri("/event")
|
||||
.accept(TEXT_EVENT_STREAM)
|
||||
.retrieve()
|
||||
.bodyToFlux(new ParameterizedTypeReference<>() {});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user