From e47f7ef7b51b8197d4c9b41c3a5b33e7cb62ef45 Mon Sep 17 00:00:00 2001 From: Brian Clozel Date: Thu, 21 Feb 2019 17:44:03 +0100 Subject: [PATCH] Remove response content-type before error handling Prior to this commit, the negotiated content-type during the request mapping phase would be kept as the response content-type header; this information is used when rendering the error response and prevents a new round of content negotiation to choose the media type that fits best. This commit removes the response content type information at the beginning of the error handling phase. Fixes gh-22452 --- .../method/annotation/RequestMappingHandlerAdapter.java | 4 ++++ .../RequestMappingExceptionHandlingIntegrationTests.java | 8 ++++---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/RequestMappingHandlerAdapter.java b/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/RequestMappingHandlerAdapter.java index fe978d18f7..6fcdee61a6 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/RequestMappingHandlerAdapter.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/RequestMappingHandlerAdapter.java @@ -29,6 +29,7 @@ import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.core.ReactiveAdapterRegistry; +import org.springframework.http.HttpHeaders; import org.springframework.http.codec.HttpMessageReader; import org.springframework.http.codec.ServerCodecConfigurer; import org.springframework.lang.Nullable; @@ -209,6 +210,9 @@ public class RequestMappingHandlerAdapter implements HandlerAdapter, Application // Success and error responses may use different content types exchange.getAttributes().remove(HandlerMapping.PRODUCIBLE_MEDIA_TYPES_ATTRIBUTE); + if (!exchange.getResponse().isCommitted()) { + exchange.getResponse().getHeaders().remove(HttpHeaders.CONTENT_TYPE); + } InvocableHandlerMethod invocable = this.methodResolver.getExceptionHandlerMethod(exception, handlerMethod); if (invocable != null) { diff --git a/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/RequestMappingExceptionHandlingIntegrationTests.java b/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/RequestMappingExceptionHandlingIntegrationTests.java index 63362edb52..d97dd9e6e3 100644 --- a/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/RequestMappingExceptionHandlingIntegrationTests.java +++ b/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/RequestMappingExceptionHandlingIntegrationTests.java @@ -93,7 +93,7 @@ public class RequestMappingExceptionHandlingIntegrationTests extends AbstractReq public void exceptionFromMethodWithProducesCondition() throws Exception { try { HttpHeaders headers = new HttpHeaders(); - headers.add("Accept", "text/csv, application/problem+json"); + headers.add("Accept", "text/plain, application/problem+json"); performGet("/SPR-16318", headers, String.class).getBody(); fail(); } @@ -152,9 +152,9 @@ public class RequestMappingExceptionHandlingIntegrationTests extends AbstractReq }); } - @GetMapping(path = "/SPR-16318", produces = "text/csv") - public String handleCsv() throws Exception { - throw new Spr16318Exception(); + @GetMapping(path = "/SPR-16318", produces = "text/plain") + public Mono handleTextPlain() throws Exception { + return Mono.error(new Spr16318Exception()); } @ExceptionHandler