diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/AbstractMessageWriterResultHandler.java b/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/AbstractMessageWriterResultHandler.java index 3fb0b39223..68919bf82a 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/AbstractMessageWriterResultHandler.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/AbstractMessageWriterResultHandler.java @@ -33,6 +33,7 @@ import org.springframework.core.ResolvableType; import org.springframework.core.codec.Hints; import org.springframework.http.MediaType; import org.springframework.http.codec.HttpMessageWriter; +import org.springframework.http.converter.HttpMessageNotWritableException; import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.web.reactive.accept.RequestedContentTypeResolver; @@ -163,7 +164,7 @@ public abstract class AbstractMessageWriterResultHandler extends HandlerResultHa MediaType contentType = exchange.getResponse().getHeaders().getContentType(); if (contentType != null && contentType.equals(bestMediaType)) { - return Mono.error(new IllegalStateException( + return Mono.error(new HttpMessageNotWritableException( "No Encoder for [" + elementType + "] with preset Content-Type '" + contentType + "'")); } 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 fa8604d1a7..5d18a61e70 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 @@ -51,6 +51,7 @@ import org.springframework.http.codec.HttpMessageWriter; import org.springframework.http.codec.ResourceHttpMessageWriter; import org.springframework.http.codec.json.Jackson2JsonEncoder; import org.springframework.http.codec.xml.Jaxb2XmlEncoder; +import org.springframework.http.converter.HttpMessageNotWritableException; import org.springframework.mock.web.test.server.MockServerWebExchange; import org.springframework.util.ObjectUtils; import org.springframework.web.reactive.HandlerResult; @@ -365,7 +366,7 @@ public class ResponseEntityResultHandlerTests { StepVerifier.create(resultHandler.handleResult(exchange, result)) .consumeErrorWith(ex -> assertThat(ex) - .isInstanceOf(IllegalStateException.class) + .isInstanceOf(HttpMessageNotWritableException.class) .hasMessageContaining("with preset Content-Type")) .verify(); } diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/AbstractMessageConverterMethodProcessor.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/AbstractMessageConverterMethodProcessor.java index 9d2f8c185a..aaf97ae658 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/AbstractMessageConverterMethodProcessor.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/AbstractMessageConverterMethodProcessor.java @@ -176,6 +176,9 @@ public abstract class AbstractMessageConverterMethodProcessor extends AbstractMe * @throws IOException thrown in case of I/O errors * @throws HttpMediaTypeNotAcceptableException thrown when the conditions indicated * by the {@code Accept} header on the request cannot be met by the message converters + * @throws HttpMessageNotWritableException thrown if a given message cannot + * be written by a converter, or if the content-type chosen by the server + * has no compatible converter. */ @SuppressWarnings({"rawtypes", "unchecked"}) protected void writeWithMessageConverters(@Nullable T value, MethodParameter returnType, @@ -306,7 +309,7 @@ public abstract class AbstractMessageConverterMethodProcessor extends AbstractMe if (body != null) { if (isContentTypePreset) { - throw new IllegalStateException( + throw new HttpMessageNotWritableException( "No converter for [" + valueType + "] with preset Content-Type '" + contentType + "'"); } throw new HttpMediaTypeNotAcceptableException(this.allSupportedMediaTypes); diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/HttpEntityMethodProcessorMockTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/HttpEntityMethodProcessorMockTests.java index 38531a621b..e8d040b1d9 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/HttpEntityMethodProcessorMockTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/HttpEntityMethodProcessorMockTests.java @@ -47,6 +47,7 @@ import org.springframework.http.MediaType; import org.springframework.http.RequestEntity; import org.springframework.http.ResponseEntity; import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.http.converter.HttpMessageNotWritableException; import org.springframework.mock.web.test.MockHttpServletRequest; import org.springframework.mock.web.test.MockHttpServletResponse; import org.springframework.web.HttpMediaTypeNotAcceptableException; @@ -59,7 +60,7 @@ import static java.time.Instant.ofEpochMilli; import static java.time.format.DateTimeFormatter.RFC_1123_DATE_TIME; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; -import static org.assertj.core.api.Assertions.assertThatIllegalStateException; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyCollection; import static org.mockito.ArgumentMatchers.argThat; @@ -325,10 +326,11 @@ public class HttpEntityMethodProcessorMockTests { given(stringHttpMessageConverter.canWrite(String.class, null)).willReturn(true); given(stringHttpMessageConverter.getSupportedMediaTypes()).willReturn(Collections.singletonList(TEXT_PLAIN)); - assertThatIllegalStateException() - .isThrownBy(() -> - processor.handleReturnValue(returnValue, returnTypeResponseEntity, mavContainer, webRequest)) - .withMessageContaining("with preset Content-Type"); + assertThatThrownBy(() -> + processor.handleReturnValue( + returnValue, returnTypeResponseEntity, mavContainer, webRequest)) + .isInstanceOf(HttpMessageNotWritableException.class) + .hasMessageContaining("with preset Content-Type"); } @Test