diff --git a/spring-core/src/main/java/org/springframework/core/codec/ByteArrayEncoder.java b/spring-core/src/main/java/org/springframework/core/codec/ByteArrayEncoder.java index 23ee1d3be4..473152225f 100644 --- a/spring-core/src/main/java/org/springframework/core/codec/ByteArrayEncoder.java +++ b/spring-core/src/main/java/org/springframework/core/codec/ByteArrayEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -42,8 +42,8 @@ public class ByteArrayEncoder extends AbstractEncoder { @Override public boolean canEncode(ResolvableType elementType, MimeType mimeType) { - Class clazz = elementType.getRawClass(); - return (super.canEncode(elementType, mimeType) && byte[].class.isAssignableFrom(clazz)); + Class clazz = elementType.resolve(Object.class); + return super.canEncode(elementType, mimeType) && byte[].class.isAssignableFrom(clazz); } @Override diff --git a/spring-core/src/main/java/org/springframework/core/codec/ByteBufferEncoder.java b/spring-core/src/main/java/org/springframework/core/codec/ByteBufferEncoder.java index afa38d0016..8e077beb61 100644 --- a/spring-core/src/main/java/org/springframework/core/codec/ByteBufferEncoder.java +++ b/spring-core/src/main/java/org/springframework/core/codec/ByteBufferEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -43,8 +43,8 @@ public class ByteBufferEncoder extends AbstractEncoder { @Override public boolean canEncode(ResolvableType elementType, MimeType mimeType) { - Class clazz = elementType.getRawClass(); - return (super.canEncode(elementType, mimeType) && ByteBuffer.class.isAssignableFrom(clazz)); + Class clazz = elementType.resolve(Object.class); + return super.canEncode(elementType, mimeType) && ByteBuffer.class.isAssignableFrom(clazz); } @Override diff --git a/spring-core/src/main/java/org/springframework/core/codec/CharSequenceEncoder.java b/spring-core/src/main/java/org/springframework/core/codec/CharSequenceEncoder.java index 0562d3dce2..a4e4be4a20 100644 --- a/spring-core/src/main/java/org/springframework/core/codec/CharSequenceEncoder.java +++ b/spring-core/src/main/java/org/springframework/core/codec/CharSequenceEncoder.java @@ -52,8 +52,8 @@ public class CharSequenceEncoder extends AbstractEncoder { @Override public boolean canEncode(ResolvableType elementType, MimeType mimeType) { - Class clazz = elementType.getRawClass(); - return (super.canEncode(elementType, mimeType) && CharSequence.class.isAssignableFrom(clazz)); + Class clazz = elementType.resolve(Object.class); + return super.canEncode(elementType, mimeType) && CharSequence.class.isAssignableFrom(clazz); } @Override diff --git a/spring-core/src/main/java/org/springframework/core/codec/DataBufferEncoder.java b/spring-core/src/main/java/org/springframework/core/codec/DataBufferEncoder.java index f9021b9860..4fa1aa7559 100644 --- a/spring-core/src/main/java/org/springframework/core/codec/DataBufferEncoder.java +++ b/spring-core/src/main/java/org/springframework/core/codec/DataBufferEncoder.java @@ -42,8 +42,8 @@ public class DataBufferEncoder extends AbstractEncoder { @Override public boolean canEncode(ResolvableType elementType, MimeType mimeType) { - Class clazz = elementType.getRawClass(); - return (super.canEncode(elementType, mimeType) && DataBuffer.class.isAssignableFrom(clazz)); + Class clazz = elementType.resolve(Object.class); + return super.canEncode(elementType, mimeType) && DataBuffer.class.isAssignableFrom(clazz); } @Override diff --git a/spring-core/src/main/java/org/springframework/core/codec/ResourceEncoder.java b/spring-core/src/main/java/org/springframework/core/codec/ResourceEncoder.java index 0f22c8a0f0..4020a1c258 100644 --- a/spring-core/src/main/java/org/springframework/core/codec/ResourceEncoder.java +++ b/spring-core/src/main/java/org/springframework/core/codec/ResourceEncoder.java @@ -61,7 +61,7 @@ public class ResourceEncoder extends AbstractSingleValueEncoder { @Override public boolean canEncode(ResolvableType elementType, MimeType mimeType) { - Class clazz = elementType.getRawClass(); + Class clazz = elementType.resolve(Object.class); return (super.canEncode(elementType, mimeType) && Resource.class.isAssignableFrom(clazz)); } diff --git a/spring-core/src/main/java/org/springframework/core/codec/ResourceRegionEncoder.java b/spring-core/src/main/java/org/springframework/core/codec/ResourceRegionEncoder.java index 0a62d8a231..8e1bbf8e51 100644 --- a/spring-core/src/main/java/org/springframework/core/codec/ResourceRegionEncoder.java +++ b/spring-core/src/main/java/org/springframework/core/codec/ResourceRegionEncoder.java @@ -69,9 +69,8 @@ public class ResourceRegionEncoder extends AbstractEncoder { @Override public boolean canEncode(ResolvableType elementType, MimeType mimeType) { - return super.canEncode(elementType, mimeType) - && ResourceRegion.class.isAssignableFrom(elementType.getRawClass()); + && ResourceRegion.class.isAssignableFrom(elementType.resolve(Object.class)); } @Override diff --git a/spring-core/src/test/java/org/springframework/core/codec/ByteArrayEncoderTests.java b/spring-core/src/test/java/org/springframework/core/codec/ByteArrayEncoderTests.java index d4248bd674..5772fa8212 100644 --- a/spring-core/src/test/java/org/springframework/core/codec/ByteArrayEncoderTests.java +++ b/spring-core/src/test/java/org/springframework/core/codec/ByteArrayEncoderTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -55,6 +55,9 @@ public class ByteArrayEncoderTests extends AbstractDataBufferAllocatingTestCase MimeTypeUtils.TEXT_PLAIN)); assertTrue(this.encoder.canEncode(ResolvableType.forClass(byte[].class), MimeTypeUtils.APPLICATION_JSON)); + + // SPR-15464 + assertFalse(this.encoder.canEncode(ResolvableType.NONE, null)); } @Test diff --git a/spring-core/src/test/java/org/springframework/core/codec/ByteBufferEncoderTests.java b/spring-core/src/test/java/org/springframework/core/codec/ByteBufferEncoderTests.java index 9882caa783..92ffc982a1 100644 --- a/spring-core/src/test/java/org/springframework/core/codec/ByteBufferEncoderTests.java +++ b/spring-core/src/test/java/org/springframework/core/codec/ByteBufferEncoderTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -55,6 +55,9 @@ public class ByteBufferEncoderTests extends AbstractDataBufferAllocatingTestCase MimeTypeUtils.TEXT_PLAIN)); assertTrue(this.encoder.canEncode(ResolvableType.forClass(ByteBuffer.class), MimeTypeUtils.APPLICATION_JSON)); + + // SPR-15464 + assertFalse(this.encoder.canEncode(ResolvableType.NONE, null)); } @Test diff --git a/spring-core/src/test/java/org/springframework/core/codec/CharSequenceEncoderTests.java b/spring-core/src/test/java/org/springframework/core/codec/CharSequenceEncoderTests.java index 1a68277cf5..b99cab1388 100644 --- a/spring-core/src/test/java/org/springframework/core/codec/CharSequenceEncoderTests.java +++ b/spring-core/src/test/java/org/springframework/core/codec/CharSequenceEncoderTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -58,6 +58,9 @@ public class CharSequenceEncoderTests extends AbstractDataBufferAllocatingTestCa MimeTypeUtils.TEXT_PLAIN)); assertFalse(this.encoder.canEncode(ResolvableType.forClass(String.class), MimeTypeUtils.APPLICATION_JSON)); + + // SPR-15464 + assertFalse(this.encoder.canEncode(ResolvableType.NONE, null)); } @Test diff --git a/spring-core/src/test/java/org/springframework/core/codec/DataBufferEncoderTests.java b/spring-core/src/test/java/org/springframework/core/codec/DataBufferEncoderTests.java index 28495b97dc..7e7ba5de69 100644 --- a/spring-core/src/test/java/org/springframework/core/codec/DataBufferEncoderTests.java +++ b/spring-core/src/test/java/org/springframework/core/codec/DataBufferEncoderTests.java @@ -47,6 +47,9 @@ public class DataBufferEncoderTests extends AbstractDataBufferAllocatingTestCase MimeTypeUtils.TEXT_PLAIN)); assertTrue(this.encoder.canEncode(ResolvableType.forClass(DataBuffer.class), MimeTypeUtils.APPLICATION_JSON)); + + // SPR-15464 + assertFalse(this.encoder.canEncode(ResolvableType.NONE, null)); } @Test diff --git a/spring-core/src/test/java/org/springframework/core/codec/ResourceEncoderTests.java b/spring-core/src/test/java/org/springframework/core/codec/ResourceEncoderTests.java index 38db56f484..7e60182807 100644 --- a/spring-core/src/test/java/org/springframework/core/codec/ResourceEncoderTests.java +++ b/spring-core/src/test/java/org/springframework/core/codec/ResourceEncoderTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,6 +32,7 @@ import org.springframework.core.io.buffer.AbstractDataBufferAllocatingTestCase; import org.springframework.core.io.buffer.DataBuffer; import org.springframework.util.MimeTypeUtils; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; /** @@ -51,6 +52,9 @@ public class ResourceEncoderTests extends AbstractDataBufferAllocatingTestCase { MimeTypeUtils.TEXT_PLAIN)); assertTrue(this.encoder.canEncode(ResolvableType.forClass(InputStreamResource.class), MimeTypeUtils.APPLICATION_JSON)); + + // SPR-15464 + assertFalse(this.encoder.canEncode(ResolvableType.NONE, null)); } @Test diff --git a/spring-core/src/test/java/org/springframework/core/codec/ResourceRegionEncoderTests.java b/spring-core/src/test/java/org/springframework/core/codec/ResourceRegionEncoderTests.java index d6540e0d28..e897c2a885 100644 --- a/spring-core/src/test/java/org/springframework/core/codec/ResourceRegionEncoderTests.java +++ b/spring-core/src/test/java/org/springframework/core/codec/ResourceRegionEncoderTests.java @@ -68,6 +68,9 @@ public class ResourceRegionEncoderTests extends AbstractDataBufferAllocatingTest assertFalse(this.encoder.canEncode(ResolvableType.forClass(Resource.class), allMimeType)); assertTrue(this.encoder.canEncode(resourceRegion, MimeTypeUtils.APPLICATION_OCTET_STREAM)); assertTrue(this.encoder.canEncode(resourceRegion, allMimeType)); + + // SPR-15464 + assertFalse(this.encoder.canEncode(ResolvableType.NONE, null)); } @Test diff --git a/spring-web/src/main/java/org/springframework/http/codec/ServerSentEventHttpMessageWriter.java b/spring-web/src/main/java/org/springframework/http/codec/ServerSentEventHttpMessageWriter.java index 1fad05f0a3..86313aca4a 100644 --- a/spring-web/src/main/java/org/springframework/http/codec/ServerSentEventHttpMessageWriter.java +++ b/spring-web/src/main/java/org/springframework/http/codec/ServerSentEventHttpMessageWriter.java @@ -86,7 +86,7 @@ public class ServerSentEventHttpMessageWriter implements HttpMessageWriter clazz = elementType.getRawClass(); - // Skip String: StringDecoder + "*/*" comes after - return (!String.class.isAssignableFrom(elementType.resolve(Object.class)) && - this.objectMapper.canSerialize(clazz) && supportsMimeType(mimeType)); + Class clazz = elementType.resolve(Object.class); + return Object.class.equals(clazz) || + !String.class.isAssignableFrom(elementType.resolve(clazz)) && + this.objectMapper.canSerialize(clazz) && supportsMimeType(mimeType); } @Override diff --git a/spring-web/src/main/java/org/springframework/http/codec/xml/Jaxb2XmlEncoder.java b/spring-web/src/main/java/org/springframework/http/codec/xml/Jaxb2XmlEncoder.java index 7866ca5c57..54e3a101e4 100644 --- a/spring-web/src/main/java/org/springframework/http/codec/xml/Jaxb2XmlEncoder.java +++ b/spring-web/src/main/java/org/springframework/http/codec/xml/Jaxb2XmlEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -55,7 +55,7 @@ public class Jaxb2XmlEncoder extends AbstractSingleValueEncoder { @Override public boolean canEncode(ResolvableType elementType, MimeType mimeType) { if (super.canEncode(elementType, mimeType)) { - Class outputClass = elementType.getRawClass(); + Class outputClass = elementType.resolve(Object.class); return (outputClass.isAnnotationPresent(XmlRootElement.class) || outputClass.isAnnotationPresent(XmlType.class)); } diff --git a/spring-web/src/test/java/org/springframework/http/codec/ServerSentEventHttpMessageWriterTests.java b/spring-web/src/test/java/org/springframework/http/codec/ServerSentEventHttpMessageWriterTests.java index 34eb086535..334f75627f 100644 --- a/spring-web/src/test/java/org/springframework/http/codec/ServerSentEventHttpMessageWriterTests.java +++ b/spring-web/src/test/java/org/springframework/http/codec/ServerSentEventHttpMessageWriterTests.java @@ -27,6 +27,7 @@ import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import reactor.test.StepVerifier; +import org.springframework.core.ResolvableType; import org.springframework.core.io.buffer.AbstractDataBufferAllocatingTestCase; import org.springframework.http.MediaType; import org.springframework.http.codec.json.Jackson2JsonEncoder; @@ -52,14 +53,16 @@ public class ServerSentEventHttpMessageWriterTests extends AbstractDataBufferAll @Test public void canWrite() { + assertTrue(this.messageWriter.canWrite(forClass(Object.class), null)); + assertFalse(this.messageWriter.canWrite(forClass(Object.class), new MediaType("foo", "bar"))); + assertTrue(this.messageWriter.canWrite(null, MediaType.TEXT_EVENT_STREAM)); assertTrue(this.messageWriter.canWrite(forClass(ServerSentEvent.class), new MediaType("foo", "bar"))); - } - @Test - public void canNotWrite() { - assertFalse(this.messageWriter.canWrite(forClass(Object.class), new MediaType("foo", "bar"))); + // SPR-15464 + assertTrue(this.messageWriter.canWrite(ResolvableType.NONE, MediaType.TEXT_EVENT_STREAM)); + assertFalse(this.messageWriter.canWrite(ResolvableType.NONE, new MediaType("foo", "bar"))); } @Test 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 56d7c83cab..33b548dd4f 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 @@ -52,6 +52,9 @@ public class Jackson2JsonEncoderTests extends AbstractDataBufferAllocatingTestCa ResolvableType pojoType = ResolvableType.forClass(Pojo.class); assertTrue(this.encoder.canEncode(pojoType, APPLICATION_JSON)); assertTrue(this.encoder.canEncode(pojoType, null)); + + // SPR-15464 + assertTrue(this.encoder.canEncode(ResolvableType.NONE, null)); } @Test diff --git a/spring-web/src/test/java/org/springframework/http/codec/xml/Jaxb2XmlEncoderTests.java b/spring-web/src/test/java/org/springframework/http/codec/xml/Jaxb2XmlEncoderTests.java index efdfa780dd..40563c3d2e 100644 --- a/spring-web/src/test/java/org/springframework/http/codec/xml/Jaxb2XmlEncoderTests.java +++ b/spring-web/src/test/java/org/springframework/http/codec/xml/Jaxb2XmlEncoderTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -60,6 +60,9 @@ public class Jaxb2XmlEncoderTests extends AbstractDataBufferAllocatingTestCase { assertFalse(this.encoder.canEncode(ResolvableType.forClass(getClass()), MediaType.APPLICATION_XML)); + + // SPR-15464 + assertFalse(this.encoder.canEncode(ResolvableType.NONE, null)); } @Test diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/ResponseEntityResultHandler.java b/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/ResponseEntityResultHandler.java index a39897dada..1ee2134184 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/ResponseEntityResultHandler.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/ResponseEntityResultHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,7 +24,6 @@ import reactor.core.publisher.Mono; import org.springframework.core.MethodParameter; import org.springframework.core.ReactiveAdapter; import org.springframework.core.ReactiveAdapterRegistry; -import org.springframework.core.ResolvableType; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; @@ -79,16 +78,15 @@ public class ResponseEntityResultHandler extends AbstractMessageWriterResultHand @Override public boolean supports(HandlerResult result) { - if (isSupportedType(result.getReturnType())) { + if (isSupportedType(result.getReturnType().getRawClass())) { return true; } ReactiveAdapter adapter = getAdapter(result); return adapter != null && !adapter.isNoValue() && - isSupportedType(result.getReturnType().getGeneric(0)); + isSupportedType(result.getReturnType().getGeneric(0).resolve(Object.class)); } - private boolean isSupportedType(ResolvableType type) { - Class clazz = type.getRawClass(); + private boolean isSupportedType(Class clazz) { return (HttpEntity.class.isAssignableFrom(clazz) && !RequestEntity.class.isAssignableFrom(clazz)); } diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/ViewResolutionResultHandler.java b/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/ViewResolutionResultHandler.java index 85ec9b9871..2787139883 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/ViewResolutionResultHandler.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/ViewResolutionResultHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -156,7 +156,7 @@ public class ViewResolutionResultHandler extends HandlerResultHandlerSupport if (adapter.isNoValue()) { return true; } - type = result.getReturnType().getGeneric(0).getRawClass(); + type = result.getReturnType().getGeneric(0).resolve(Object.class); } return (CharSequence.class.isAssignableFrom(type) || Rendering.class.isAssignableFrom(type) || Model.class.isAssignableFrom(type) || Map.class.isAssignableFrom(type) || diff --git a/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/ResponseEntityResultHandlerTests.java b/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/ResponseEntityResultHandlerTests.java index f27fb75b34..704a7d34ed 100644 --- a/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/ResponseEntityResultHandlerTests.java +++ b/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/ResponseEntityResultHandlerTests.java @@ -29,6 +29,7 @@ import java.util.concurrent.CompletableFuture; import org.junit.Before; import org.junit.Test; +import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import reactor.test.StepVerifier; import rx.Completable; @@ -132,6 +133,10 @@ public class ResponseEntityResultHandlerTests { returnType = on(TestController.class).resolveReturnType(Completable.class); assertFalse(this.resultHandler.supports(handlerResult(value, returnType))); + + // SPR-15464 + returnType = on(TestController.class).resolveReturnType(Flux.class); + assertFalse(this.resultHandler.supports(handlerResult(value, returnType))); } @Test @@ -381,6 +386,7 @@ public class ResponseEntityResultHandlerTests { Mono> monoResponseEntityWildcard() { return null; } + Flux fluxWildcard() { return null; } } } diff --git a/spring-webflux/src/test/java/org/springframework/web/reactive/result/view/ViewResolutionResultHandlerTests.java b/spring-webflux/src/test/java/org/springframework/web/reactive/result/view/ViewResolutionResultHandlerTests.java index 8b693d5663..2810011bb0 100644 --- a/spring-webflux/src/test/java/org/springframework/web/reactive/result/view/ViewResolutionResultHandlerTests.java +++ b/spring-webflux/src/test/java/org/springframework/web/reactive/result/view/ViewResolutionResultHandlerTests.java @@ -97,6 +97,9 @@ public class ViewResolutionResultHandlerTests { testSupports(on(Handler.class).annotPresent(ModelAttribute.class).resolveReturnType(Long.class)); testDoesNotSupport(on(Handler.class).annotNotPresent(ModelAttribute.class).resolveReturnType(Long.class)); + + // SPR-15464 + testSupports(on(Handler.class).resolveReturnType(Mono.class)); } private void testSupports(MethodParameter returnType) { @@ -427,6 +430,7 @@ public class ViewResolutionResultHandlerTests { Long longValue() { return null; } @ModelAttribute("myLong") Long longModelAttribute() { return null; } + Mono monoWildcard() { return null; } } }