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);
}
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());
}
}
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);
}
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));
}
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);
}
}
Aggregations