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
This commit is contained in:
@@ -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<HandlerMethod> 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
|
||||
|
||||
@@ -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<HandlerMethod> getHandlerInternal(ServerWebExchange exchange) {
|
||||
return super.getHandlerInternal(exchange)
|
||||
.doOnTerminate(() -> ProducesRequestCondition.clearMediaTypesAttribute(exchange));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user