Skip to content

Commit c10266e

Browse files
committed
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
1 parent 1b6b163 commit c10266e

File tree

9 files changed

+19
-19
lines changed

9 files changed

+19
-19
lines changed

spring-web/src/main/java/org/springframework/http/codec/AbstractJacksonDecoder.java

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -102,14 +102,7 @@ public int getMaxInMemorySize() {
102102

103103
@Override
104104
public boolean canDecode(ResolvableType elementType, @Nullable MimeType mimeType) {
105-
if (!supportsMimeType(mimeType)) {
106-
return false;
107-
}
108-
T mapper = selectMapper(elementType, mimeType);
109-
if (mapper == null) {
110-
return false;
111-
}
112-
return !CharSequence.class.isAssignableFrom(elementType.toClass());
105+
return supportsMimeType(mimeType) && (selectMapper(elementType, mimeType) != null);
113106
}
114107

115108
@Override

spring-web/src/main/java/org/springframework/http/codec/AbstractJacksonEncoder.java

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -126,14 +126,11 @@ public boolean canEncode(ResolvableType elementType, @Nullable MimeType mimeType
126126
if (this.mapperRegistrations != null && selectMapper(elementType, mimeType) == null) {
127127
return false;
128128
}
129-
Class<?> clazz = elementType.resolve();
130-
if (clazz == null) {
131-
return true;
132-
}
133-
if (MappingJacksonValue.class.isAssignableFrom(clazz)) {
129+
Class<?> elementClass = elementType.toClass();
130+
if (MappingJacksonValue.class.isAssignableFrom(elementClass)) {
134131
throw new UnsupportedOperationException("MappingJacksonValue is not supported, use hints instead");
135132
}
136-
return !String.class.isAssignableFrom(clazz);
133+
return !ServerSentEvent.class.isAssignableFrom(elementClass);
137134
}
138135

139136
@Override

spring-web/src/main/java/org/springframework/http/codec/json/JacksonJsonDecoder.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,11 @@ public JacksonJsonDecoder(JsonMapper mapper, MimeType... mimeTypes) {
104104
super(mapper, mimeTypes);
105105
}
106106

107+
@Override
108+
public boolean canDecode(ResolvableType elementType, @Nullable MimeType mimeType) {
109+
return super.canDecode(elementType, mimeType) && !CharSequence.class.isAssignableFrom(elementType.toClass());
110+
}
111+
107112
@Override
108113
protected Flux<DataBuffer> processInput(Publisher<DataBuffer> input, ResolvableType elementType,
109114
@Nullable MimeType mimeType, @Nullable Map<String, Object> hints) {

spring-web/src/main/java/org/springframework/http/codec/json/JacksonJsonEncoder.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,11 @@ private static PrettyPrinter initSsePrettyPrinter() {
121121
}
122122

123123

124+
@Override
125+
public boolean canEncode(ResolvableType elementType, @Nullable MimeType mimeType) {
126+
return super.canEncode(elementType, mimeType) && !String.class.isAssignableFrom(elementType.toClass());
127+
}
128+
124129
@Override
125130
protected List<MimeType> getMediaTypesForProblemDetail() {
126131
return problemDetailMimeTypes;

spring-web/src/test/java/org/springframework/http/codec/cbor/JacksonCborDecoderTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ protected void canDecode() {
5757
assertThat(decoder.canDecode(ResolvableType.forClass(Pojo.class), MediaType.APPLICATION_CBOR)).isTrue();
5858
assertThat(decoder.canDecode(ResolvableType.forClass(Pojo.class), null)).isTrue();
5959

60-
assertThat(decoder.canDecode(ResolvableType.forClass(String.class), null)).isFalse();
60+
assertThat(decoder.canDecode(ResolvableType.forClass(String.class), null)).isTrue();
6161
assertThat(decoder.canDecode(ResolvableType.forClass(Pojo.class), APPLICATION_JSON)).isFalse();
6262
}
6363

spring-web/src/test/java/org/springframework/http/codec/cbor/JacksonCborEncoderTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,14 +59,14 @@ void canEncode() {
5959
ResolvableType pojoType = ResolvableType.forClass(Pojo.class);
6060
assertThat(this.encoder.canEncode(pojoType, MediaType.APPLICATION_CBOR)).isTrue();
6161
assertThat(this.encoder.canEncode(pojoType, null)).isTrue();
62+
assertThat(this.encoder.canEncode(ResolvableType.forClass(String.class), null)).isTrue();
6263

6364
// SPR-15464
6465
assertThat(this.encoder.canEncode(ResolvableType.NONE, null)).isTrue();
6566
}
6667

6768
@Test
6869
void canNotEncode() {
69-
assertThat(this.encoder.canEncode(ResolvableType.forClass(String.class), null)).isFalse();
7070
assertThat(this.encoder.canEncode(ResolvableType.forClass(Pojo.class), APPLICATION_XML)).isFalse();
7171
}
7272

spring-web/src/test/java/org/springframework/http/codec/smile/JacksonSmileDecoderTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ protected void canDecode() {
6262
assertThat(decoder.canDecode(ResolvableType.forClass(Pojo.class), STREAM_SMILE_MIME_TYPE)).isTrue();
6363
assertThat(decoder.canDecode(ResolvableType.forClass(Pojo.class), null)).isTrue();
6464

65-
assertThat(decoder.canDecode(ResolvableType.forClass(String.class), null)).isFalse();
65+
assertThat(decoder.canDecode(ResolvableType.forClass(String.class), null)).isTrue();
6666
assertThat(decoder.canDecode(ResolvableType.forClass(Pojo.class), APPLICATION_JSON)).isFalse();
6767
}
6868

spring-web/src/test/java/org/springframework/http/codec/smile/JacksonSmileEncoderTests.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,14 +65,15 @@ protected void canEncode() {
6565
assertThat(this.encoder.canEncode(pojoType, SMILE_MIME_TYPE)).isTrue();
6666
assertThat(this.encoder.canEncode(pojoType, STREAM_SMILE_MIME_TYPE)).isTrue();
6767
assertThat(this.encoder.canEncode(pojoType, null)).isTrue();
68+
assertThat(this.encoder.canEncode(ResolvableType.forClass(String.class), null)).isTrue();
6869

6970
// SPR-15464
7071
assertThat(this.encoder.canEncode(ResolvableType.NONE, null)).isTrue();
7172
}
7273

7374
@Test
7475
void cannotEncode() {
75-
assertThat(this.encoder.canEncode(ResolvableType.forClass(String.class), null)).isFalse();
76+
7677
assertThat(this.encoder.canEncode(ResolvableType.forClass(Pojo.class), APPLICATION_XML)).isFalse();
7778
}
7879

spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/SseIntegrationTests.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,6 @@ void sseAsEventWithoutAcceptHeader(HttpServer httpServer, ClientHttpConnector co
146146

147147
Flux<ServerSentEvent<Person>> result = this.webClient.get()
148148
.uri("/event")
149-
.accept(TEXT_EVENT_STREAM)
150149
.retrieve()
151150
.bodyToFlux(new ParameterizedTypeReference<>() {});
152151

0 commit comments

Comments
 (0)