diff --git a/spring-web/src/main/java/org/springframework/http/codec/json/Jackson2CodecSupport.java b/spring-web/src/main/java/org/springframework/http/codec/json/Jackson2CodecSupport.java index 6096b5abcc33..a8e93c258c9a 100644 --- a/spring-web/src/main/java/org/springframework/http/codec/json/Jackson2CodecSupport.java +++ b/spring-web/src/main/java/org/springframework/http/codec/json/Jackson2CodecSupport.java @@ -72,7 +72,8 @@ public abstract class Jackson2CodecSupport { protected Jackson2CodecSupport(ObjectMapper objectMapper, MimeType... mimeTypes) { Assert.notNull(objectMapper, "ObjectMapper must not be null"); this.objectMapper = objectMapper; - this.mimeTypes = !ObjectUtils.isEmpty(mimeTypes) ? Arrays.asList(mimeTypes) : JSON_MIME_TYPES; + this.mimeTypes = Collections.unmodifiableList( + !ObjectUtils.isEmpty(mimeTypes) ? Arrays.asList(mimeTypes) : JSON_MIME_TYPES ); } @@ -110,4 +111,7 @@ protected MethodParameter getParameter(ResolvableType type) { @Nullable protected abstract A getAnnotation(MethodParameter parameter, Class annotType); + protected List getMimeTypes() { + return mimeTypes; + } } diff --git a/spring-web/src/main/java/org/springframework/http/codec/json/Jackson2JsonDecoder.java b/spring-web/src/main/java/org/springframework/http/codec/json/Jackson2JsonDecoder.java index b7ea22ba8379..e108c134f105 100644 --- a/spring-web/src/main/java/org/springframework/http/codec/json/Jackson2JsonDecoder.java +++ b/spring-web/src/main/java/org/springframework/http/codec/json/Jackson2JsonDecoder.java @@ -42,6 +42,6 @@ public Jackson2JsonDecoder(ObjectMapper mapper, MimeType... mimeTypes) { @Override public List getDecodableMimeTypes() { - return JSON_MIME_TYPES; + return getMimeTypes(); } } diff --git a/spring-web/src/main/java/org/springframework/http/codec/json/Jackson2JsonEncoder.java b/spring-web/src/main/java/org/springframework/http/codec/json/Jackson2JsonEncoder.java index ddc506f20535..3ceeac108140 100644 --- a/spring-web/src/main/java/org/springframework/http/codec/json/Jackson2JsonEncoder.java +++ b/spring-web/src/main/java/org/springframework/http/codec/json/Jackson2JsonEncoder.java @@ -73,6 +73,6 @@ protected ObjectWriter customizeWriter(ObjectWriter writer, @Nullable MimeType m @Override public List getEncodableMimeTypes() { - return JSON_MIME_TYPES; + return getMimeTypes(); } } diff --git a/spring-web/src/test/java/org/springframework/http/codec/json/Jackson2JsonDecoderTests.java b/spring-web/src/test/java/org/springframework/http/codec/json/Jackson2JsonDecoderTests.java index e22603797e31..32cf14c83d28 100644 --- a/spring-web/src/test/java/org/springframework/http/codec/json/Jackson2JsonDecoderTests.java +++ b/spring-web/src/test/java/org/springframework/http/codec/json/Jackson2JsonDecoderTests.java @@ -16,12 +16,13 @@ package org.springframework.http.codec.json; +import java.nio.charset.StandardCharsets; import java.util.List; import java.util.Map; import com.fasterxml.jackson.databind.ObjectMapper; -import org.junit.Ignore; import org.junit.Test; +import org.springframework.util.MimeType; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import reactor.test.StepVerifier; @@ -63,6 +64,21 @@ public void canDecode() { assertFalse(decoder.canDecode(forClass(Pojo.class), APPLICATION_XML)); } + @Test(expected = UnsupportedOperationException.class) + public void canDecodeWithProvidedMimeType() { + MimeType textJavascript = new MimeType("text", "javascript", StandardCharsets.UTF_8); + Jackson2JsonDecoder decoder = new Jackson2JsonDecoder(new ObjectMapper(), textJavascript); + assertEquals(1, decoder.getDecodableMimeTypes().size()); + assertTrue(decoder.getDecodableMimeTypes().contains(textJavascript)); + + assertTrue(decoder.canDecode(forClass(Pojo.class), textJavascript)); + assertFalse(decoder.canDecode(forClass(Pojo.class), APPLICATION_JSON)); + + // Validate immutability of mime types list + decoder.getMimeTypes().add(new MimeType("text", "ecmascript")); + assertEquals(1, decoder.getDecodableMimeTypes().size()); + } + @Test public void decodePojo() throws Exception { Flux source = Flux.just(stringBuffer("{\"foo\": \"foofoo\", \"bar\": \"barbar\"}")); diff --git a/spring-web/src/test/java/org/springframework/http/codec/json/Jackson2JsonEncoderTests.java b/spring-web/src/test/java/org/springframework/http/codec/json/Jackson2JsonEncoderTests.java index c7fe522c9f82..cdb0ea5508a4 100644 --- a/spring-web/src/test/java/org/springframework/http/codec/json/Jackson2JsonEncoderTests.java +++ b/spring-web/src/test/java/org/springframework/http/codec/json/Jackson2JsonEncoderTests.java @@ -16,16 +16,20 @@ package org.springframework.http.codec.json; +import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.Map; import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeName; import static java.util.Collections.*; +import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.Test; +import static org.junit.Assert.assertEquals; import static org.springframework.http.MediaType.*; import static org.springframework.http.codec.json.Jackson2JsonEncoder.*; import static org.springframework.http.codec.json.JacksonViewBean.*; +import org.springframework.util.MimeType; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import reactor.test.StepVerifier; @@ -58,6 +62,21 @@ public void canEncode() { assertTrue(this.encoder.canEncode(ResolvableType.NONE, null)); } + @Test(expected = UnsupportedOperationException.class) + public void canEncodeWithCustomMimeType() { + ResolvableType pojoType = ResolvableType.forClass(Pojo.class); + MimeType textJavascript = new MimeType("text", "javascript", StandardCharsets.UTF_8); + Jackson2JsonEncoder encoder = new Jackson2JsonEncoder(new ObjectMapper(), textJavascript); + assertEquals(1, encoder.getEncodableMimeTypes().size()); + assertTrue(encoder.getEncodableMimeTypes().contains(textJavascript)); + + assertTrue(encoder.canEncode(pojoType, textJavascript)); + + // Validate immutability of mime types list + encoder.getMimeTypes().add(new MimeType("text", "ecmascript")); + assertEquals(1, encoder.getEncodableMimeTypes().size()); + } + @Test public void canNotEncode() { assertFalse(this.encoder.canEncode(ResolvableType.forClass(String.class), null));