Merge branch '5.1.x'
This commit is contained in:
@@ -117,8 +117,8 @@ public abstract class HandlerResultHandlerSupport implements Ordered {
|
||||
* @return the selected media type, or {@code null} if none
|
||||
*/
|
||||
@Nullable
|
||||
protected MediaType selectMediaType(ServerWebExchange exchange,
|
||||
Supplier<List<MediaType>> producibleTypesSupplier) {
|
||||
protected MediaType selectMediaType(
|
||||
ServerWebExchange exchange, Supplier<List<MediaType>> producibleTypesSupplier) {
|
||||
|
||||
MediaType contentType = exchange.getResponse().getHeaders().getContentType();
|
||||
if (contentType != null && contentType.isConcrete()) {
|
||||
@@ -157,8 +157,8 @@ public abstract class HandlerResultHandlerSupport implements Ordered {
|
||||
|
||||
if (selected != null) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Using '" + selected + "' given " +
|
||||
acceptableTypes + " and supported " + producibleTypes);
|
||||
logger.debug("Using '" + selected + "' given " + acceptableTypes +
|
||||
" and supported " + producibleTypes);
|
||||
}
|
||||
}
|
||||
else if (logger.isDebugEnabled()) {
|
||||
@@ -173,9 +173,8 @@ public abstract class HandlerResultHandlerSupport implements Ordered {
|
||||
return getContentTypeResolver().resolveMediaTypes(exchange);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private List<MediaType> getProducibleTypes(ServerWebExchange exchange,
|
||||
Supplier<List<MediaType>> producibleTypesSupplier) {
|
||||
private List<MediaType> getProducibleTypes(
|
||||
ServerWebExchange exchange, Supplier<List<MediaType>> producibleTypesSupplier) {
|
||||
|
||||
Set<MediaType> mediaTypes = exchange.getAttribute(HandlerMapping.PRODUCIBLE_MEDIA_TYPES_ATTRIBUTE);
|
||||
return (mediaTypes != null ? new ArrayList<>(mediaTypes) : producibleTypesSupplier.get());
|
||||
|
||||
@@ -33,8 +33,6 @@ 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.server.reactive.ServerHttpRequest;
|
||||
import org.springframework.http.server.reactive.ServerHttpResponse;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.reactive.accept.RequestedContentTypeResolver;
|
||||
@@ -145,10 +143,7 @@ public abstract class AbstractMessageWriterResultHandler extends HandlerResultHa
|
||||
return Mono.from((Publisher<Void>) publisher);
|
||||
}
|
||||
|
||||
ServerHttpRequest request = exchange.getRequest();
|
||||
ServerHttpResponse response = exchange.getResponse();
|
||||
List<MediaType> writableMediaTypes = getMediaTypesFor(elementType);
|
||||
MediaType bestMediaType = selectMediaType(exchange, () -> writableMediaTypes);
|
||||
MediaType bestMediaType = selectMediaType(exchange, () -> getMediaTypesFor(elementType));
|
||||
if (bestMediaType != null) {
|
||||
String logPrefix = exchange.getLogPrefix();
|
||||
if (logger.isDebugEnabled()) {
|
||||
@@ -157,18 +152,18 @@ public abstract class AbstractMessageWriterResultHandler extends HandlerResultHa
|
||||
}
|
||||
for (HttpMessageWriter<?> writer : getMessageWriters()) {
|
||||
if (writer.canWrite(elementType, bestMediaType)) {
|
||||
return writer.write((Publisher) publisher, actualType, elementType, bestMediaType,
|
||||
request, response, Hints.from(Hints.LOG_PREFIX_HINT, logPrefix));
|
||||
return writer.write((Publisher) publisher, actualType, elementType,
|
||||
bestMediaType, exchange.getRequest(), exchange.getResponse(),
|
||||
Hints.from(Hints.LOG_PREFIX_HINT, logPrefix));
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (writableMediaTypes.isEmpty()) {
|
||||
return Mono.error(new IllegalStateException("No writer for : " + elementType));
|
||||
}
|
||||
}
|
||||
|
||||
return Mono.error(new NotAcceptableStatusException(writableMediaTypes));
|
||||
List<MediaType> mediaTypes = getMediaTypesFor(elementType);
|
||||
if (bestMediaType == null && mediaTypes.isEmpty()) {
|
||||
return Mono.error(new IllegalStateException("No HttpMessageWriter for " + elementType));
|
||||
}
|
||||
return Mono.error(new NotAcceptableStatusException(mediaTypes));
|
||||
}
|
||||
|
||||
private ResolvableType getElementType(ReactiveAdapter adapter, ResolvableType genericType) {
|
||||
@@ -193,6 +188,7 @@ public abstract class AbstractMessageWriterResultHandler extends HandlerResultHa
|
||||
return writableMediaTypes;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Inner class to avoid a hard dependency on Kotlin at runtime.
|
||||
*/
|
||||
|
||||
@@ -113,56 +113,56 @@ class ControllerMethodResolver {
|
||||
private final Map<Class<?>, SessionAttributesHandler> sessionAttributesHandlerCache = new ConcurrentHashMap<>(64);
|
||||
|
||||
|
||||
ControllerMethodResolver(ArgumentResolverConfigurer customResolvers, ReactiveAdapterRegistry reactiveRegistry,
|
||||
ControllerMethodResolver(ArgumentResolverConfigurer customResolvers, ReactiveAdapterRegistry adapterRegistry,
|
||||
ConfigurableApplicationContext context, List<HttpMessageReader<?>> readers) {
|
||||
|
||||
Assert.notNull(customResolvers, "ArgumentResolverConfigurer is required");
|
||||
Assert.notNull(readers, "'messageReaders' is required");
|
||||
Assert.notNull(reactiveRegistry, "ReactiveAdapterRegistry is required");
|
||||
Assert.notNull(adapterRegistry, "ReactiveAdapterRegistry is required");
|
||||
Assert.notNull(context, "ApplicationContext is required");
|
||||
Assert.notNull(readers, "HttpMessageReader List is required");
|
||||
|
||||
this.initBinderResolvers = initBinderResolvers(customResolvers, reactiveRegistry, context);
|
||||
this.modelAttributeResolvers = modelMethodResolvers(customResolvers, reactiveRegistry, context);
|
||||
this.requestMappingResolvers = requestMappingResolvers(customResolvers, reactiveRegistry, context, readers);
|
||||
this.exceptionHandlerResolvers = exceptionHandlerResolvers(customResolvers, reactiveRegistry, context);
|
||||
this.reactiveAdapterRegistry = reactiveRegistry;
|
||||
this.initBinderResolvers = initBinderResolvers(customResolvers, adapterRegistry, context);
|
||||
this.modelAttributeResolvers = modelMethodResolvers(customResolvers, adapterRegistry, context);
|
||||
this.requestMappingResolvers = requestMappingResolvers(customResolvers, adapterRegistry, context, readers);
|
||||
this.exceptionHandlerResolvers = exceptionHandlerResolvers(customResolvers, adapterRegistry, context);
|
||||
this.reactiveAdapterRegistry = adapterRegistry;
|
||||
|
||||
initControllerAdviceCaches(context);
|
||||
}
|
||||
|
||||
private List<SyncHandlerMethodArgumentResolver> initBinderResolvers(
|
||||
ArgumentResolverConfigurer customResolvers, ReactiveAdapterRegistry reactiveRegistry,
|
||||
ArgumentResolverConfigurer customResolvers, ReactiveAdapterRegistry adapterRegistry,
|
||||
ConfigurableApplicationContext context) {
|
||||
|
||||
return initResolvers(customResolvers, reactiveRegistry, context, false, Collections.emptyList()).stream()
|
||||
return initResolvers(customResolvers, adapterRegistry, context, false, Collections.emptyList()).stream()
|
||||
.filter(resolver -> resolver instanceof SyncHandlerMethodArgumentResolver)
|
||||
.map(resolver -> (SyncHandlerMethodArgumentResolver) resolver)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private static List<HandlerMethodArgumentResolver> modelMethodResolvers(
|
||||
ArgumentResolverConfigurer customResolvers, ReactiveAdapterRegistry reactiveRegistry,
|
||||
ArgumentResolverConfigurer customResolvers, ReactiveAdapterRegistry adapterRegistry,
|
||||
ConfigurableApplicationContext context) {
|
||||
|
||||
return initResolvers(customResolvers, reactiveRegistry, context, true, Collections.emptyList());
|
||||
return initResolvers(customResolvers, adapterRegistry, context, true, Collections.emptyList());
|
||||
}
|
||||
|
||||
private static List<HandlerMethodArgumentResolver> requestMappingResolvers(
|
||||
ArgumentResolverConfigurer customResolvers, ReactiveAdapterRegistry reactiveRegistry,
|
||||
ArgumentResolverConfigurer customResolvers, ReactiveAdapterRegistry adapterRegistry,
|
||||
ConfigurableApplicationContext context, List<HttpMessageReader<?>> readers) {
|
||||
|
||||
return initResolvers(customResolvers, reactiveRegistry, context, true, readers);
|
||||
return initResolvers(customResolvers, adapterRegistry, context, true, readers);
|
||||
}
|
||||
|
||||
private static List<HandlerMethodArgumentResolver> exceptionHandlerResolvers(
|
||||
ArgumentResolverConfigurer customResolvers, ReactiveAdapterRegistry reactiveRegistry,
|
||||
ArgumentResolverConfigurer customResolvers, ReactiveAdapterRegistry adapterRegistry,
|
||||
ConfigurableApplicationContext context) {
|
||||
|
||||
return initResolvers(customResolvers, reactiveRegistry, context, false, Collections.emptyList());
|
||||
return initResolvers(customResolvers, adapterRegistry, context, false, Collections.emptyList());
|
||||
}
|
||||
|
||||
private static List<HandlerMethodArgumentResolver> initResolvers(ArgumentResolverConfigurer customResolvers,
|
||||
ReactiveAdapterRegistry reactiveRegistry, ConfigurableApplicationContext context,
|
||||
ReactiveAdapterRegistry adapterRegistry, ConfigurableApplicationContext context,
|
||||
boolean supportDataBinding, List<HttpMessageReader<?>> readers) {
|
||||
|
||||
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
|
||||
@@ -170,51 +170,51 @@ class ControllerMethodResolver {
|
||||
|
||||
// Annotation-based...
|
||||
List<HandlerMethodArgumentResolver> result = new ArrayList<>();
|
||||
result.add(new RequestParamMethodArgumentResolver(beanFactory, reactiveRegistry, false));
|
||||
result.add(new RequestParamMapMethodArgumentResolver(reactiveRegistry));
|
||||
result.add(new PathVariableMethodArgumentResolver(beanFactory, reactiveRegistry));
|
||||
result.add(new PathVariableMapMethodArgumentResolver(reactiveRegistry));
|
||||
result.add(new MatrixVariableMethodArgumentResolver(beanFactory, reactiveRegistry));
|
||||
result.add(new MatrixVariableMapMethodArgumentResolver(reactiveRegistry));
|
||||
result.add(new RequestParamMethodArgumentResolver(beanFactory, adapterRegistry, false));
|
||||
result.add(new RequestParamMapMethodArgumentResolver(adapterRegistry));
|
||||
result.add(new PathVariableMethodArgumentResolver(beanFactory, adapterRegistry));
|
||||
result.add(new PathVariableMapMethodArgumentResolver(adapterRegistry));
|
||||
result.add(new MatrixVariableMethodArgumentResolver(beanFactory, adapterRegistry));
|
||||
result.add(new MatrixVariableMapMethodArgumentResolver(adapterRegistry));
|
||||
if (!readers.isEmpty()) {
|
||||
result.add(new RequestBodyArgumentResolver(readers, reactiveRegistry));
|
||||
result.add(new RequestPartMethodArgumentResolver(readers, reactiveRegistry));
|
||||
result.add(new RequestBodyArgumentResolver(readers, adapterRegistry));
|
||||
result.add(new RequestPartMethodArgumentResolver(readers, adapterRegistry));
|
||||
}
|
||||
if (supportDataBinding) {
|
||||
result.add(new ModelAttributeMethodArgumentResolver(reactiveRegistry, false));
|
||||
result.add(new ModelAttributeMethodArgumentResolver(adapterRegistry, false));
|
||||
}
|
||||
result.add(new RequestHeaderMethodArgumentResolver(beanFactory, reactiveRegistry));
|
||||
result.add(new RequestHeaderMapMethodArgumentResolver(reactiveRegistry));
|
||||
result.add(new CookieValueMethodArgumentResolver(beanFactory, reactiveRegistry));
|
||||
result.add(new ExpressionValueMethodArgumentResolver(beanFactory, reactiveRegistry));
|
||||
result.add(new SessionAttributeMethodArgumentResolver(beanFactory, reactiveRegistry));
|
||||
result.add(new RequestAttributeMethodArgumentResolver(beanFactory, reactiveRegistry));
|
||||
result.add(new RequestHeaderMethodArgumentResolver(beanFactory, adapterRegistry));
|
||||
result.add(new RequestHeaderMapMethodArgumentResolver(adapterRegistry));
|
||||
result.add(new CookieValueMethodArgumentResolver(beanFactory, adapterRegistry));
|
||||
result.add(new ExpressionValueMethodArgumentResolver(beanFactory, adapterRegistry));
|
||||
result.add(new SessionAttributeMethodArgumentResolver(beanFactory, adapterRegistry));
|
||||
result.add(new RequestAttributeMethodArgumentResolver(beanFactory, adapterRegistry));
|
||||
|
||||
// Type-based...
|
||||
if (KotlinDetector.isKotlinPresent()) {
|
||||
result.add(new ContinuationHandlerMethodArgumentResolver());
|
||||
}
|
||||
if (!readers.isEmpty()) {
|
||||
result.add(new HttpEntityArgumentResolver(readers, reactiveRegistry));
|
||||
result.add(new HttpEntityArgumentResolver(readers, adapterRegistry));
|
||||
}
|
||||
result.add(new ModelArgumentResolver(reactiveRegistry));
|
||||
result.add(new ModelArgumentResolver(adapterRegistry));
|
||||
if (supportDataBinding) {
|
||||
result.add(new ErrorsMethodArgumentResolver(reactiveRegistry));
|
||||
result.add(new ErrorsMethodArgumentResolver(adapterRegistry));
|
||||
}
|
||||
result.add(new ServerWebExchangeArgumentResolver(reactiveRegistry));
|
||||
result.add(new PrincipalArgumentResolver(reactiveRegistry));
|
||||
result.add(new ServerWebExchangeArgumentResolver(adapterRegistry));
|
||||
result.add(new PrincipalArgumentResolver(adapterRegistry));
|
||||
if (requestMappingMethod) {
|
||||
result.add(new SessionStatusMethodArgumentResolver());
|
||||
}
|
||||
result.add(new WebSessionArgumentResolver(reactiveRegistry));
|
||||
result.add(new WebSessionArgumentResolver(adapterRegistry));
|
||||
|
||||
// Custom...
|
||||
result.addAll(customResolvers.getCustomResolvers());
|
||||
|
||||
// Catch-all...
|
||||
result.add(new RequestParamMethodArgumentResolver(beanFactory, reactiveRegistry, true));
|
||||
result.add(new RequestParamMethodArgumentResolver(beanFactory, adapterRegistry, true));
|
||||
if (supportDataBinding) {
|
||||
result.add(new ModelAttributeMethodArgumentResolver(reactiveRegistry, true));
|
||||
result.add(new ModelAttributeMethodArgumentResolver(adapterRegistry, true));
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2019 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.
|
||||
@@ -160,10 +160,10 @@ public class ModelAttributeMethodArgumentResolver extends HandlerMethodArgumentR
|
||||
return createAttribute(attributeName, attributeType.toClass(), context, exchange);
|
||||
}
|
||||
|
||||
ReactiveAdapter adapterFrom = getAdapterRegistry().getAdapter(null, attribute);
|
||||
if (adapterFrom != null) {
|
||||
Assert.isTrue(!adapterFrom.isMultiValue(), "Data binding only supports single-value async types");
|
||||
return Mono.from(adapterFrom.toPublisher(attribute));
|
||||
ReactiveAdapter adapter = getAdapterRegistry().getAdapter(null, attribute);
|
||||
if (adapter != null) {
|
||||
Assert.isTrue(!adapter.isMultiValue(), "Data binding only supports single-value async types");
|
||||
return Mono.from(adapter.toPublisher(attribute));
|
||||
}
|
||||
else {
|
||||
return Mono.justOrEmpty(attribute);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2019 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.
|
||||
@@ -57,7 +57,7 @@ public abstract class AbstractView implements View, BeanNameAware, ApplicationCo
|
||||
private static final Object NO_VALUE = new Object();
|
||||
|
||||
|
||||
private final ReactiveAdapterRegistry reactiveAdapterRegistry;
|
||||
private final ReactiveAdapterRegistry adapterRegistry;
|
||||
|
||||
private final List<MediaType> mediaTypes = new ArrayList<>(4);
|
||||
|
||||
@@ -78,7 +78,7 @@ public abstract class AbstractView implements View, BeanNameAware, ApplicationCo
|
||||
}
|
||||
|
||||
public AbstractView(ReactiveAdapterRegistry reactiveAdapterRegistry) {
|
||||
this.reactiveAdapterRegistry = reactiveAdapterRegistry;
|
||||
this.adapterRegistry = reactiveAdapterRegistry;
|
||||
this.mediaTypes.add(ViewResolverSupport.DEFAULT_CONTENT_TYPE);
|
||||
}
|
||||
|
||||
@@ -240,7 +240,7 @@ public abstract class AbstractView implements View, BeanNameAware, ApplicationCo
|
||||
if (value == null) {
|
||||
continue;
|
||||
}
|
||||
ReactiveAdapter adapter = this.reactiveAdapterRegistry.getAdapter(null, value);
|
||||
ReactiveAdapter adapter = this.adapterRegistry.getAdapter(null, value);
|
||||
if (adapter != null) {
|
||||
names.add(entry.getKey());
|
||||
if (adapter.isMultiValue()) {
|
||||
|
||||
Reference in New Issue
Block a user