From 68b980f8498a7a07004ed05547400f4997252bad Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Tue, 18 Feb 2020 21:50:38 +0000 Subject: [PATCH] Remove producible request attribute before mapping The attribute was previously removed only before exception resolution in the DispatcherServlet in order to allow error rendering to make an independent choice on content negotation. However, Boot rendering happens later in an ERROR dispatch which could also be a nested dispatch on some servers. So the attribute must also generally be removed prior to mapping. We also move the methods where this is done to the base RequestMappingInfoHandlerMapping class which also deals with the produces condition and where the producible attribute is added in the first place. Closes gh-24466 --- .../method/RequestMappingInfoHandlerMapping.java | 10 ++++++++++ .../annotation/RequestMappingHandlerMapping.java | 12 +----------- .../method/RequestMappingInfoHandlerMapping.java | 14 +++++++++++++- .../annotation/RequestMappingHandlerMapping.java | 11 ----------- 4 files changed, 24 insertions(+), 23 deletions(-) diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/RequestMappingInfoHandlerMapping.java b/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/RequestMappingInfoHandlerMapping.java index 3e66ed8c48..eaccc21222 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/RequestMappingInfoHandlerMapping.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/RequestMappingInfoHandlerMapping.java @@ -27,6 +27,8 @@ import java.util.Map; import java.util.Set; import java.util.stream.Collectors; +import reactor.core.publisher.Mono; + import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.http.InvalidMediaTypeException; @@ -38,6 +40,7 @@ import org.springframework.util.MultiValueMap; import org.springframework.web.method.HandlerMethod; import org.springframework.web.reactive.HandlerMapping; import org.springframework.web.reactive.result.condition.NameValueExpression; +import org.springframework.web.reactive.result.condition.ProducesRequestCondition; import org.springframework.web.server.MethodNotAllowedException; import org.springframework.web.server.NotAcceptableStatusException; import org.springframework.web.server.ServerWebExchange; @@ -87,6 +90,13 @@ public abstract class RequestMappingInfoHandlerMapping extends AbstractHandlerMe return (info1, info2) -> info1.compareTo(info2, exchange); } + @Override + public Mono getHandlerInternal(ServerWebExchange exchange) { + exchange.getAttributes().remove(HandlerMapping.PRODUCIBLE_MEDIA_TYPES_ATTRIBUTE); + return super.getHandlerInternal(exchange) + .doOnTerminate(() -> ProducesRequestCondition.clearMediaTypesAttribute(exchange)); + } + /** * Expose URI template variables, matrix variables, and producible media types in the request. * @see HandlerMapping#URI_TEMPLATE_VARIABLES_ATTRIBUTE diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/RequestMappingHandlerMapping.java b/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/RequestMappingHandlerMapping.java index e6e0751aba..fa82f405f7 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/RequestMappingHandlerMapping.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/RequestMappingHandlerMapping.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2020 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,8 +24,6 @@ import java.util.LinkedHashMap; import java.util.Map; import java.util.function.Predicate; -import reactor.core.publisher.Mono; - import org.springframework.context.EmbeddedValueResolverAware; import org.springframework.core.annotation.AnnotatedElementUtils; import org.springframework.core.annotation.MergedAnnotation; @@ -45,11 +43,9 @@ import org.springframework.web.method.HandlerMethod; import org.springframework.web.reactive.accept.RequestedContentTypeResolver; import org.springframework.web.reactive.accept.RequestedContentTypeResolverBuilder; import org.springframework.web.reactive.result.condition.ConsumesRequestCondition; -import org.springframework.web.reactive.result.condition.ProducesRequestCondition; import org.springframework.web.reactive.result.condition.RequestCondition; import org.springframework.web.reactive.result.method.RequestMappingInfo; import org.springframework.web.reactive.result.method.RequestMappingInfoHandlerMapping; -import org.springframework.web.server.ServerWebExchange; /** * An extension of {@link RequestMappingInfoHandlerMapping} that creates @@ -356,10 +352,4 @@ public class RequestMappingHandlerMapping extends RequestMappingInfoHandlerMappi } } - @Override - public Mono getHandlerInternal(ServerWebExchange exchange) { - return super.getHandlerInternal(exchange) - .doOnTerminate(() -> ProducesRequestCondition.clearMediaTypesAttribute(exchange)); - } - } diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/RequestMappingInfoHandlerMapping.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/RequestMappingInfoHandlerMapping.java index 6e352b2336..0d6bd80895 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/RequestMappingInfoHandlerMapping.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/RequestMappingInfoHandlerMapping.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2020 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. @@ -45,6 +45,7 @@ import org.springframework.web.method.HandlerMethod; import org.springframework.web.servlet.HandlerMapping; import org.springframework.web.servlet.handler.AbstractHandlerMethodMapping; import org.springframework.web.servlet.mvc.condition.NameValueExpression; +import org.springframework.web.servlet.mvc.condition.ProducesRequestCondition; import org.springframework.web.util.WebUtils; /** @@ -102,6 +103,17 @@ public abstract class RequestMappingInfoHandlerMapping extends AbstractHandlerMe return (info1, info2) -> info1.compareTo(info2, request); } + @Override + protected HandlerMethod getHandlerInternal(HttpServletRequest request) throws Exception { + request.removeAttribute(PRODUCIBLE_MEDIA_TYPES_ATTRIBUTE); + try { + return super.getHandlerInternal(request); + } + finally { + ProducesRequestCondition.clearMediaTypesAttribute(request); + } + } + /** * Expose URI template variables, matrix variables, and producible media types in the request. * @see HandlerMapping#URI_TEMPLATE_VARIABLES_ATTRIBUTE diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerMapping.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerMapping.java index 5b6d42ed49..9b679e4938 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerMapping.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerMapping.java @@ -49,7 +49,6 @@ import org.springframework.web.servlet.handler.RequestMatchResult; import org.springframework.web.servlet.mvc.condition.AbstractRequestCondition; import org.springframework.web.servlet.mvc.condition.CompositeRequestCondition; import org.springframework.web.servlet.mvc.condition.ConsumesRequestCondition; -import org.springframework.web.servlet.mvc.condition.ProducesRequestCondition; import org.springframework.web.servlet.mvc.condition.RequestCondition; import org.springframework.web.servlet.mvc.method.RequestMappingInfo; import org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping; @@ -473,14 +472,4 @@ public class RequestMappingHandlerMapping extends RequestMappingInfoHandlerMappi } } - @Override - protected HandlerMethod getHandlerInternal(HttpServletRequest request) throws Exception { - try { - return super.getHandlerInternal(request); - } - finally { - ProducesRequestCondition.clearMediaTypesAttribute(request); - } - } - }