Search in sources :

Example 6 with NotAcceptableStatusException

use of org.springframework.web.server.NotAcceptableStatusException in project spring-framework by spring-projects.

the class AbstractResponseStatusExceptionHandlerTests method handleResponseStatusExceptionWithHeaders.

// gh-23741
@Test
public void handleResponseStatusExceptionWithHeaders() {
    Throwable ex = new NotAcceptableStatusException(Arrays.asList(MediaType.TEXT_PLAIN, MediaType.TEXT_HTML));
    this.handler.handle(this.exchange, ex).block(Duration.ofSeconds(5));
    MockServerHttpResponse response = this.exchange.getResponse();
    assertThat(response.getStatusCode()).isEqualTo(HttpStatus.NOT_ACCEPTABLE);
    assertThat(response.getHeaders().getAccept()).containsOnly(MediaType.TEXT_PLAIN, MediaType.TEXT_HTML);
}
Also used : NotAcceptableStatusException(org.springframework.web.server.NotAcceptableStatusException) MockServerHttpResponse(org.springframework.web.testfixture.http.server.reactive.MockServerHttpResponse) Test(org.junit.jupiter.api.Test)

Example 7 with NotAcceptableStatusException

use of org.springframework.web.server.NotAcceptableStatusException in project spring-framework by spring-projects.

the class HeaderContentTypeResolver method resolveMediaTypes.

@Override
public List<MediaType> resolveMediaTypes(ServerWebExchange exchange) throws NotAcceptableStatusException {
    try {
        List<MediaType> mediaTypes = exchange.getRequest().getHeaders().getAccept();
        MimeTypeUtils.sortBySpecificity(mediaTypes);
        return (!CollectionUtils.isEmpty(mediaTypes) ? mediaTypes : MEDIA_TYPE_ALL_LIST);
    } catch (InvalidMediaTypeException ex) {
        String value = exchange.getRequest().getHeaders().getFirst("Accept");
        throw new NotAcceptableStatusException("Could not parse 'Accept' header [" + value + "]: " + ex.getMessage());
    }
}
Also used : NotAcceptableStatusException(org.springframework.web.server.NotAcceptableStatusException) MediaType(org.springframework.http.MediaType) InvalidMediaTypeException(org.springframework.http.InvalidMediaTypeException)

Example 8 with NotAcceptableStatusException

use of org.springframework.web.server.NotAcceptableStatusException in project spring-framework by spring-projects.

the class ParameterContentTypeResolver method resolveMediaTypes.

@Override
public List<MediaType> resolveMediaTypes(ServerWebExchange exchange) throws NotAcceptableStatusException {
    String key = exchange.getRequest().getQueryParams().getFirst(getParameterName());
    if (!StringUtils.hasText(key)) {
        return MEDIA_TYPE_ALL_LIST;
    }
    key = formatKey(key);
    MediaType match = this.mediaTypes.get(key);
    if (match == null) {
        match = MediaTypeFactory.getMediaType("filename." + key).orElseThrow(() -> {
            List<MediaType> supported = new ArrayList<>(this.mediaTypes.values());
            return new NotAcceptableStatusException(supported);
        });
    }
    this.mediaTypes.putIfAbsent(key, match);
    return Collections.singletonList(match);
}
Also used : NotAcceptableStatusException(org.springframework.web.server.NotAcceptableStatusException) MediaType(org.springframework.http.MediaType) List(java.util.List) ArrayList(java.util.ArrayList)

Example 9 with NotAcceptableStatusException

use of org.springframework.web.server.NotAcceptableStatusException in project spring-framework by spring-projects.

the class AbstractMessageWriterResultHandler method writeBody.

/**
 * Write a given body to the response with {@link HttpMessageWriter}.
 * @param body the object to write
 * @param bodyParameter the {@link MethodParameter} of the body to write
 * @param actualParam the actual return type of the method that returned the value;
 * could be different from {@code bodyParameter} when processing {@code HttpEntity}
 * for example
 * @param exchange the current exchange
 * @return indicates completion or error
 * @since 5.0.2
 */
@SuppressWarnings({ "unchecked", "rawtypes", "ConstantConditions" })
protected Mono<Void> writeBody(@Nullable Object body, MethodParameter bodyParameter, @Nullable MethodParameter actualParam, ServerWebExchange exchange) {
    ResolvableType bodyType = ResolvableType.forMethodParameter(bodyParameter);
    ResolvableType actualType = (actualParam != null ? ResolvableType.forMethodParameter(actualParam) : bodyType);
    ReactiveAdapter adapter = getAdapterRegistry().getAdapter(bodyType.resolve(), body);
    Publisher<?> publisher;
    ResolvableType elementType;
    ResolvableType actualElementType;
    if (adapter != null) {
        publisher = adapter.toPublisher(body);
        boolean isUnwrapped = KotlinDetector.isSuspendingFunction(bodyParameter.getMethod()) && !COROUTINES_FLOW_CLASS_NAME.equals(bodyType.toClass().getName());
        ResolvableType genericType = isUnwrapped ? bodyType : bodyType.getGeneric();
        elementType = getElementType(adapter, genericType);
        actualElementType = elementType;
    } else {
        publisher = Mono.justOrEmpty(body);
        actualElementType = body != null ? ResolvableType.forInstance(body) : bodyType;
        elementType = (bodyType.toClass() == Object.class && body != null ? actualElementType : bodyType);
    }
    if (elementType.resolve() == void.class || elementType.resolve() == Void.class) {
        return Mono.from((Publisher<Void>) publisher);
    }
    MediaType bestMediaType;
    try {
        bestMediaType = selectMediaType(exchange, () -> getMediaTypesFor(elementType));
    } catch (NotAcceptableStatusException ex) {
        HttpStatus statusCode = exchange.getResponse().getStatusCode();
        if (statusCode != null && statusCode.isError()) {
            if (logger.isDebugEnabled()) {
                logger.debug("Ignoring error response content (if any). " + ex.getReason());
            }
            return Mono.empty();
        }
        throw ex;
    }
    if (bestMediaType != null) {
        String logPrefix = exchange.getLogPrefix();
        if (logger.isDebugEnabled()) {
            logger.debug(logPrefix + (publisher instanceof Mono ? "0..1" : "0..N") + " [" + elementType + "]");
        }
        for (HttpMessageWriter<?> writer : getMessageWriters()) {
            if (writer.canWrite(actualElementType, bestMediaType)) {
                return writer.write((Publisher) publisher, actualType, elementType, bestMediaType, exchange.getRequest(), exchange.getResponse(), Hints.from(Hints.LOG_PREFIX_HINT, logPrefix));
            }
        }
    }
    MediaType contentType = exchange.getResponse().getHeaders().getContentType();
    boolean isPresentMediaType = (contentType != null && contentType.equals(bestMediaType));
    Set<MediaType> producibleTypes = exchange.getAttribute(HandlerMapping.PRODUCIBLE_MEDIA_TYPES_ATTRIBUTE);
    if (isPresentMediaType || !CollectionUtils.isEmpty(producibleTypes)) {
        return Mono.error(new HttpMessageNotWritableException("No Encoder for [" + elementType + "] with preset Content-Type '" + contentType + "'"));
    }
    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));
}
Also used : NotAcceptableStatusException(org.springframework.web.server.NotAcceptableStatusException) HttpStatus(org.springframework.http.HttpStatus) Mono(reactor.core.publisher.Mono) HttpMessageNotWritableException(org.springframework.http.converter.HttpMessageNotWritableException) MediaType(org.springframework.http.MediaType) ResolvableType(org.springframework.core.ResolvableType) ReactiveAdapter(org.springframework.core.ReactiveAdapter)

Example 10 with NotAcceptableStatusException

use of org.springframework.web.server.NotAcceptableStatusException in project spring-framework by spring-projects.

the class ProducesRequestCondition method compareTo.

/**
 * Compares this and another "produces" condition as follows:
 * <ol>
 * <li>Sort 'Accept' header media types by quality value via
 * {@link org.springframework.util.MimeTypeUtils#sortBySpecificity(List)}
 * and iterate the list.
 * <li>Get the first index of matching media types in each "produces"
 * condition first matching with {@link MediaType#equals(Object)} and
 * then with {@link MediaType#includes(MediaType)}.
 * <li>If a lower index is found, the condition at that index wins.
 * <li>If both indexes are equal, the media types at the index are
 * compared further with {@link MediaType#isMoreSpecific(MimeType)}.
 * </ol>
 * <p>It is assumed that both instances have been obtained via
 * {@link #getMatchingCondition(ServerWebExchange)} and each instance
 * contains the matching producible media type expression only or
 * is otherwise empty.
 */
@Override
public int compareTo(ProducesRequestCondition other, ServerWebExchange exchange) {
    try {
        List<MediaType> acceptedMediaTypes = getAcceptedMediaTypes(exchange);
        for (MediaType acceptedMediaType : acceptedMediaTypes) {
            int thisIndex = this.indexOfEqualMediaType(acceptedMediaType);
            int otherIndex = other.indexOfEqualMediaType(acceptedMediaType);
            int result = compareMatchingMediaTypes(this, thisIndex, other, otherIndex);
            if (result != 0) {
                return result;
            }
            thisIndex = this.indexOfIncludedMediaType(acceptedMediaType);
            otherIndex = other.indexOfIncludedMediaType(acceptedMediaType);
            result = compareMatchingMediaTypes(this, thisIndex, other, otherIndex);
            if (result != 0) {
                return result;
            }
        }
        return 0;
    } catch (NotAcceptableStatusException ex) {
        // should never happen
        throw new IllegalStateException("Cannot compare without having any requested media types", ex);
    }
}
Also used : NotAcceptableStatusException(org.springframework.web.server.NotAcceptableStatusException) MediaType(org.springframework.http.MediaType)

Aggregations

NotAcceptableStatusException (org.springframework.web.server.NotAcceptableStatusException)12 MediaType (org.springframework.http.MediaType)11 InvalidMediaTypeException (org.springframework.http.InvalidMediaTypeException)4 ReactiveAdapter (org.springframework.core.ReactiveAdapter)2 ResolvableType (org.springframework.core.ResolvableType)2 HttpMethod (org.springframework.http.HttpMethod)2 HttpStatus (org.springframework.http.HttpStatus)2 ServerHttpRequest (org.springframework.http.server.reactive.ServerHttpRequest)2 HandlerMethod (org.springframework.web.method.HandlerMethod)2 MethodNotAllowedException (org.springframework.web.server.MethodNotAllowedException)2 ServerWebInputException (org.springframework.web.server.ServerWebInputException)2 UnsupportedMediaTypeStatusException (org.springframework.web.server.UnsupportedMediaTypeStatusException)2 ArrayList (java.util.ArrayList)1 List (java.util.List)1 Test (org.junit.jupiter.api.Test)1 HttpMessageWriter (org.springframework.http.codec.HttpMessageWriter)1 HttpMessageNotWritableException (org.springframework.http.converter.HttpMessageNotWritableException)1 MockServerHttpResponse (org.springframework.web.testfixture.http.server.reactive.MockServerHttpResponse)1 Mono (reactor.core.publisher.Mono)1