use of org.springframework.core.ReactiveAdapter in project spring-framework by spring-projects.
the class HandlerMethodArgumentResolverSupport method checkAnnotatedParamNoReactiveWrapper.
/**
* Evaluate the {@code Predicate} on the method parameter type if it has the
* given annotation, nesting within {@link java.util.Optional} if necessary,
* but raise an {@code IllegalStateException} if the same matches the generic
* type within a reactive type wrapper.
*/
protected <A extends Annotation> boolean checkAnnotatedParamNoReactiveWrapper(MethodParameter parameter, Class<A> annotationType, BiPredicate<A, Class<?>> typePredicate) {
A annotation = parameter.getParameterAnnotation(annotationType);
if (annotation == null) {
return false;
}
parameter = parameter.nestedIfOptional();
Class<?> type = parameter.getNestedParameterType();
ReactiveAdapter adapter = getAdapterRegistry().getAdapter(type);
if (adapter != null) {
assertHasValues(adapter, parameter);
parameter = parameter.nested();
type = parameter.getNestedParameterType();
}
if (typePredicate.test(annotation, type)) {
if (adapter == null) {
return true;
}
throw buildReactiveWrapperException(parameter);
}
return false;
}
use of org.springframework.core.ReactiveAdapter in project spring-framework by spring-projects.
the class HandlerMethodArgumentResolverSupport method checkParameterTypeNoReactiveWrapper.
/**
* Evaluate the {@code Predicate} on the method parameter type but raise an
* {@code IllegalStateException} if the same matches the generic type
* within a reactive type wrapper.
*/
protected boolean checkParameterTypeNoReactiveWrapper(MethodParameter parameter, Predicate<Class<?>> predicate) {
Class<?> type = parameter.getParameterType();
ReactiveAdapter adapter = getAdapterRegistry().getAdapter(type);
if (adapter != null) {
assertHasValues(adapter, parameter);
type = parameter.nested().getNestedParameterType();
}
if (predicate.test(type)) {
if (adapter == null) {
return true;
}
throw buildReactiveWrapperException(parameter);
}
return false;
}
use of org.springframework.core.ReactiveAdapter in project spring-framework by spring-projects.
the class AbstractMessageReaderArgumentResolver method readBody.
/**
* Read the body from a method argument with {@link HttpMessageReader}.
* @param bodyParam represents the element type for the body
* @param actualParam the actual method argument type; possibly different
* from {@code bodyParam}, e.g. for an {@code HttpEntity} argument
* @param isBodyRequired true if the body is required
* @param bindingContext the binding context to use
* @param exchange the current exchange
* @return a Mono with the value to use for the method argument
* @since 5.0.2
*/
protected Mono<Object> readBody(MethodParameter bodyParam, @Nullable MethodParameter actualParam, boolean isBodyRequired, BindingContext bindingContext, ServerWebExchange exchange) {
ResolvableType bodyType = ResolvableType.forMethodParameter(bodyParam);
ResolvableType actualType = (actualParam != null ? ResolvableType.forMethodParameter(actualParam) : bodyType);
Class<?> resolvedType = bodyType.resolve();
ReactiveAdapter adapter = (resolvedType != null ? getAdapterRegistry().getAdapter(resolvedType) : null);
ResolvableType elementType = (adapter != null ? bodyType.getGeneric() : bodyType);
isBodyRequired = isBodyRequired || (adapter != null && !adapter.supportsEmpty());
ServerHttpRequest request = exchange.getRequest();
ServerHttpResponse response = exchange.getResponse();
MediaType contentType = request.getHeaders().getContentType();
MediaType mediaType = (contentType != null ? contentType : MediaType.APPLICATION_OCTET_STREAM);
Object[] hints = extractValidationHints(bodyParam);
if (mediaType.isCompatibleWith(MediaType.APPLICATION_FORM_URLENCODED)) {
if (logger.isDebugEnabled()) {
logger.debug("Form data is accessed via ServerWebExchange.getFormData() in WebFlux.");
}
return Mono.error(new ResponseStatusException(HttpStatus.UNSUPPORTED_MEDIA_TYPE));
}
if (logger.isDebugEnabled()) {
logger.debug(exchange.getLogPrefix() + (contentType != null ? "Content-Type:" + contentType : "No Content-Type, using " + MediaType.APPLICATION_OCTET_STREAM));
}
for (HttpMessageReader<?> reader : getMessageReaders()) {
if (reader.canRead(elementType, mediaType)) {
Map<String, Object> readHints = Hints.from(Hints.LOG_PREFIX_HINT, exchange.getLogPrefix());
if (adapter != null && adapter.isMultiValue()) {
if (logger.isDebugEnabled()) {
logger.debug(exchange.getLogPrefix() + "0..N [" + elementType + "]");
}
Flux<?> flux = reader.read(actualType, elementType, request, response, readHints);
flux = flux.onErrorResume(ex -> Flux.error(handleReadError(bodyParam, ex)));
if (isBodyRequired) {
flux = flux.switchIfEmpty(Flux.error(() -> handleMissingBody(bodyParam)));
}
if (hints != null) {
flux = flux.doOnNext(target -> validate(target, hints, bodyParam, bindingContext, exchange));
}
return Mono.just(adapter.fromPublisher(flux));
} else {
// Single-value (with or without reactive type wrapper)
if (logger.isDebugEnabled()) {
logger.debug(exchange.getLogPrefix() + "0..1 [" + elementType + "]");
}
Mono<?> mono = reader.readMono(actualType, elementType, request, response, readHints);
mono = mono.onErrorResume(ex -> Mono.error(handleReadError(bodyParam, ex)));
if (isBodyRequired) {
mono = mono.switchIfEmpty(Mono.error(() -> handleMissingBody(bodyParam)));
}
if (hints != null) {
mono = mono.doOnNext(target -> validate(target, hints, bodyParam, bindingContext, exchange));
}
return (adapter != null ? Mono.just(adapter.fromPublisher(mono)) : Mono.from(mono));
}
}
}
// No compatible reader but body may be empty..
HttpMethod method = request.getMethod();
if (contentType == null && SUPPORTED_METHODS.contains(method)) {
Flux<DataBuffer> body = request.getBody().doOnNext(buffer -> {
DataBufferUtils.release(buffer);
// Body not empty, back toy 415..
throw new UnsupportedMediaTypeStatusException(mediaType, getSupportedMediaTypes(elementType), elementType);
});
if (isBodyRequired) {
body = body.switchIfEmpty(Mono.error(() -> handleMissingBody(bodyParam)));
}
return (adapter != null ? Mono.just(adapter.fromPublisher(body)) : Mono.from(body));
}
return Mono.error(new UnsupportedMediaTypeStatusException(mediaType, getSupportedMediaTypes(elementType), elementType));
}
use of org.springframework.core.ReactiveAdapter in project spring-framework by spring-projects.
the class WebSessionMethodArgumentResolver method resolveArgument.
@Override
public Mono<Object> resolveArgument(MethodParameter parameter, BindingContext context, ServerWebExchange exchange) {
Mono<WebSession> session = exchange.getSession();
ReactiveAdapter adapter = getAdapterRegistry().getAdapter(parameter.getParameterType());
return (adapter != null ? Mono.just(adapter.fromPublisher(session)) : Mono.from(session));
}
use of org.springframework.core.ReactiveAdapter in project spring-framework by spring-projects.
the class ModelAttributeMethodArgumentResolver method prepareAttributeMono.
private Mono<?> prepareAttributeMono(String attributeName, ResolvableType attributeType, BindingContext context, ServerWebExchange exchange) {
Object attribute = context.getModel().asMap().get(attributeName);
if (attribute == null) {
attribute = findAndRemoveReactiveAttribute(context.getModel(), attributeName);
}
if (attribute == null) {
return createAttribute(attributeName, attributeType.toClass(), context, exchange);
}
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);
}
}
Aggregations