Apply new ResponseStatusException hierarchy
This commit replaces use of the existing ServletException-based exceptions with the new ones from ~.web.server.
This commit is contained in:
@@ -1,30 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2015 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.web.reactive;
|
||||
|
||||
import org.springframework.core.NestedRuntimeException;
|
||||
|
||||
/**
|
||||
* @author Rossen Stoyanchev
|
||||
*/
|
||||
public class HandlerNotFoundException extends NestedRuntimeException {
|
||||
|
||||
|
||||
public HandlerNotFoundException() {
|
||||
super("No handler found.");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -29,7 +29,7 @@ import org.springframework.http.MediaType;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.HttpMediaTypeNotAcceptableException;
|
||||
import org.springframework.web.server.NotAcceptableStatusException;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
|
||||
/**
|
||||
@@ -85,7 +85,7 @@ public abstract class AbstractMappingContentTypeResolver implements MappingConte
|
||||
|
||||
@Override
|
||||
public List<MediaType> resolveMediaTypes(ServerWebExchange exchange)
|
||||
throws HttpMediaTypeNotAcceptableException {
|
||||
throws NotAcceptableStatusException {
|
||||
|
||||
String key = extractKey(exchange);
|
||||
return resolveMediaTypes(key);
|
||||
@@ -95,11 +95,9 @@ public abstract class AbstractMappingContentTypeResolver implements MappingConte
|
||||
* An overloaded resolve method with a pre-resolved lookup key.
|
||||
* @param key the key for looking up media types
|
||||
* @return a list of resolved media types or an empty list
|
||||
* @throws HttpMediaTypeNotAcceptableException
|
||||
* @throws NotAcceptableStatusException
|
||||
*/
|
||||
public List<MediaType> resolveMediaTypes(String key)
|
||||
throws HttpMediaTypeNotAcceptableException {
|
||||
|
||||
public List<MediaType> resolveMediaTypes(String key) throws NotAcceptableStatusException {
|
||||
if (StringUtils.hasText(key)) {
|
||||
MediaType mediaType = getMediaType(key);
|
||||
if (mediaType != null) {
|
||||
@@ -139,7 +137,7 @@ public abstract class AbstractMappingContentTypeResolver implements MappingConte
|
||||
* this method it will be added to the mappings.
|
||||
*/
|
||||
@SuppressWarnings("UnusedParameters")
|
||||
protected MediaType handleNoMatch(String key) throws HttpMediaTypeNotAcceptableException {
|
||||
protected MediaType handleNoMatch(String key) throws NotAcceptableStatusException {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ import java.util.Set;
|
||||
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.HttpMediaTypeNotAcceptableException;
|
||||
import org.springframework.web.server.NotAcceptableStatusException;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
|
||||
/**
|
||||
@@ -71,7 +71,7 @@ public class CompositeContentTypeResolver implements MappingContentTypeResolver
|
||||
|
||||
|
||||
@Override
|
||||
public List<MediaType> resolveMediaTypes(ServerWebExchange exchange) throws HttpMediaTypeNotAcceptableException {
|
||||
public List<MediaType> resolveMediaTypes(ServerWebExchange exchange) throws NotAcceptableStatusException {
|
||||
for (ContentTypeResolver resolver : this.resolvers) {
|
||||
List<MediaType> mediaTypes = resolver.resolveMediaTypes(exchange);
|
||||
if (mediaTypes.isEmpty() || (mediaTypes.size() == 1 && mediaTypes.contains(MediaType.ALL))) {
|
||||
|
||||
@@ -18,7 +18,7 @@ package org.springframework.web.reactive.accept;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.web.HttpMediaTypeNotAcceptableException;
|
||||
import org.springframework.web.server.NotAcceptableStatusException;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
|
||||
/**
|
||||
@@ -34,9 +34,8 @@ public interface ContentTypeResolver {
|
||||
* @param exchange the current exchange
|
||||
* @return the requested media types or an empty list
|
||||
*
|
||||
* @throws HttpMediaTypeNotAcceptableException if the requested media
|
||||
* types cannot be parsed
|
||||
* @throws NotAcceptableStatusException if the requested media types is invalid
|
||||
*/
|
||||
List<MediaType> resolveMediaTypes(ServerWebExchange exchange) throws HttpMediaTypeNotAcceptableException;
|
||||
List<MediaType> resolveMediaTypes(ServerWebExchange exchange) throws NotAcceptableStatusException;
|
||||
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ import java.util.List;
|
||||
|
||||
import org.springframework.http.InvalidMediaTypeException;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.web.HttpMediaTypeNotAcceptableException;
|
||||
import org.springframework.web.server.NotAcceptableStatusException;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
|
||||
/**
|
||||
@@ -30,9 +30,7 @@ import org.springframework.web.server.ServerWebExchange;
|
||||
public class HeaderContentTypeResolver implements ContentTypeResolver {
|
||||
|
||||
@Override
|
||||
public List<MediaType> resolveMediaTypes(ServerWebExchange exchange)
|
||||
throws HttpMediaTypeNotAcceptableException {
|
||||
|
||||
public List<MediaType> resolveMediaTypes(ServerWebExchange exchange) throws NotAcceptableStatusException {
|
||||
try {
|
||||
List<MediaType> mediaTypes = exchange.getRequest().getHeaders().getAccept();
|
||||
MediaType.sortBySpecificityAndQuality(mediaTypes);
|
||||
@@ -40,8 +38,9 @@ public class HeaderContentTypeResolver implements ContentTypeResolver {
|
||||
}
|
||||
catch (InvalidMediaTypeException ex) {
|
||||
String value = exchange.getRequest().getHeaders().getFirst("Accept");
|
||||
throw new HttpMediaTypeNotAcceptableException(
|
||||
throw new NotAcceptableStatusException(
|
||||
"Could not parse 'Accept' header [" + value + "]: " + ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.HttpMediaTypeNotAcceptableException;
|
||||
import org.springframework.web.server.NotAcceptableStatusException;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
|
||||
/**
|
||||
@@ -75,8 +75,8 @@ public class ParameterContentTypeResolver extends AbstractMappingContentTypeReso
|
||||
}
|
||||
|
||||
@Override
|
||||
protected MediaType handleNoMatch(String key) throws HttpMediaTypeNotAcceptableException {
|
||||
throw new HttpMediaTypeNotAcceptableException(getMediaTypes());
|
||||
protected MediaType handleNoMatch(String key) throws NotAcceptableStatusException {
|
||||
throw new NotAcceptableStatusException(getMediaTypes());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -31,8 +31,7 @@ import org.springframework.http.MediaType;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.HttpMediaTypeNotAcceptableException;
|
||||
import org.springframework.web.accept.PathExtensionContentNegotiationStrategy;
|
||||
import org.springframework.web.server.NotAcceptableStatusException;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
import org.springframework.web.util.WebUtils;
|
||||
|
||||
@@ -49,11 +48,10 @@ import org.springframework.web.util.WebUtils;
|
||||
*/
|
||||
public class PathExtensionContentTypeResolver extends AbstractMappingContentTypeResolver {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(PathExtensionContentNegotiationStrategy.class);
|
||||
private static final Log logger = LogFactory.getLog(PathExtensionContentTypeResolver.class);
|
||||
|
||||
private static final boolean JAF_PRESENT = ClassUtils.isPresent(
|
||||
"javax.activation.FileTypeMap",
|
||||
PathExtensionContentNegotiationStrategy.class.getClassLoader());
|
||||
private static final boolean JAF_PRESENT = ClassUtils.isPresent("javax.activation.FileTypeMap",
|
||||
PathExtensionContentTypeResolver.class.getClassLoader());
|
||||
|
||||
|
||||
private boolean useJaf = true;
|
||||
@@ -104,7 +102,7 @@ public class PathExtensionContentTypeResolver extends AbstractMappingContentType
|
||||
}
|
||||
|
||||
@Override
|
||||
protected MediaType handleNoMatch(String key) throws HttpMediaTypeNotAcceptableException {
|
||||
protected MediaType handleNoMatch(String key) throws NotAcceptableStatusException {
|
||||
if (this.useJaf && JAF_PRESENT) {
|
||||
MediaType mediaType = JafMediaTypeFactory.getMediaType("file." + key);
|
||||
if (mediaType != null && !MediaType.APPLICATION_OCTET_STREAM.equals(mediaType)) {
|
||||
@@ -112,7 +110,7 @@ public class PathExtensionContentTypeResolver extends AbstractMappingContentType
|
||||
}
|
||||
}
|
||||
if (!this.ignoreUnknownExtensions) {
|
||||
throw new HttpMediaTypeNotAcceptableException(getMediaTypes());
|
||||
throw new NotAcceptableStatusException(getMediaTypes());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -20,9 +20,10 @@ import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.web.HttpMediaTypeException;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.server.NotAcceptableStatusException;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
import org.springframework.web.server.UnsupportedMediaTypeStatusException;
|
||||
|
||||
/**
|
||||
* Supports media type expressions as described in:
|
||||
@@ -72,12 +73,16 @@ abstract class AbstractMediaTypeExpression implements Comparable<AbstractMediaTy
|
||||
boolean match = matchMediaType(exchange);
|
||||
return (!this.isNegated == match);
|
||||
}
|
||||
catch (HttpMediaTypeException ex) {
|
||||
catch (NotAcceptableStatusException ex) {
|
||||
return false;
|
||||
}
|
||||
catch (UnsupportedMediaTypeStatusException ex) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract boolean matchMediaType(ServerWebExchange exchange) throws HttpMediaTypeException;
|
||||
protected abstract boolean matchMediaType(ServerWebExchange exchange)
|
||||
throws NotAcceptableStatusException, UnsupportedMediaTypeStatusException;
|
||||
|
||||
|
||||
@Override
|
||||
|
||||
@@ -26,9 +26,9 @@ import java.util.Set;
|
||||
|
||||
import org.springframework.http.InvalidMediaTypeException;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.web.HttpMediaTypeNotSupportedException;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
import org.springframework.web.server.UnsupportedMediaTypeStatusException;
|
||||
|
||||
/**
|
||||
* A logical disjunction (' || ') request condition to match a request's
|
||||
@@ -217,14 +217,14 @@ public final class ConsumesRequestCondition extends AbstractRequestCondition<Con
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean matchMediaType(ServerWebExchange exchange) throws HttpMediaTypeNotSupportedException {
|
||||
protected boolean matchMediaType(ServerWebExchange exchange) throws UnsupportedMediaTypeStatusException {
|
||||
try {
|
||||
MediaType contentType = exchange.getRequest().getHeaders().getContentType();
|
||||
contentType = (contentType != null ? contentType : MediaType.APPLICATION_OCTET_STREAM);
|
||||
return getMediaType().includes(contentType);
|
||||
}
|
||||
catch (InvalidMediaTypeException ex) {
|
||||
throw new HttpMediaTypeNotSupportedException("Can't parse Content-Type [" +
|
||||
throw new UnsupportedMediaTypeStatusException("Can't parse Content-Type [" +
|
||||
exchange.getRequest().getHeaders().getFirst("Content-Type") +
|
||||
"]: " + ex.getMessage());
|
||||
}
|
||||
|
||||
@@ -25,12 +25,12 @@ import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.web.HttpMediaTypeNotAcceptableException;
|
||||
import org.springframework.web.accept.ContentNegotiationManager;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.reactive.accept.CompositeContentTypeResolverBuilder;
|
||||
import org.springframework.web.reactive.accept.ContentTypeResolver;
|
||||
import org.springframework.web.reactive.accept.HeaderContentTypeResolver;
|
||||
import org.springframework.web.server.NotAcceptableStatusException;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
|
||||
/**
|
||||
@@ -234,14 +234,14 @@ public final class ProducesRequestCondition extends AbstractRequestCondition<Pro
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
catch (HttpMediaTypeNotAcceptableException ex) {
|
||||
catch (NotAcceptableStatusException ex) {
|
||||
// should never happen
|
||||
throw new IllegalStateException("Cannot compare without having any requested media types", ex);
|
||||
}
|
||||
}
|
||||
|
||||
private List<MediaType> getAcceptedMediaTypes(ServerWebExchange exchange)
|
||||
throws HttpMediaTypeNotAcceptableException {
|
||||
throws NotAcceptableStatusException {
|
||||
|
||||
List<MediaType> mediaTypes = this.contentTypeResolver.resolveMediaTypes(exchange);
|
||||
return mediaTypes.isEmpty() ? Collections.singletonList(MediaType.ALL) : mediaTypes;
|
||||
@@ -306,7 +306,7 @@ public final class ProducesRequestCondition extends AbstractRequestCondition<Pro
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean matchMediaType(ServerWebExchange exchange) throws HttpMediaTypeNotAcceptableException {
|
||||
protected boolean matchMediaType(ServerWebExchange exchange) throws NotAcceptableStatusException {
|
||||
List<MediaType> acceptedMediaTypes = getAcceptedMediaTypes(exchange);
|
||||
for (MediaType acceptedMediaType : acceptedMediaTypes) {
|
||||
if (getMediaType().isCompatibleWith(acceptedMediaType)) {
|
||||
|
||||
@@ -36,16 +36,16 @@ import org.springframework.http.MediaType;
|
||||
import org.springframework.http.server.reactive.ServerHttpRequest;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.web.HttpMediaTypeNotAcceptableException;
|
||||
import org.springframework.web.HttpMediaTypeNotSupportedException;
|
||||
import org.springframework.web.HttpRequestMethodNotSupportedException;
|
||||
import org.springframework.web.bind.UnsatisfiedServletRequestParameterException;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
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.ParamsRequestCondition;
|
||||
import org.springframework.web.server.BadRequestStatusException;
|
||||
import org.springframework.web.server.MethodNotAllowedException;
|
||||
import org.springframework.web.server.NotAcceptableStatusException;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
import org.springframework.web.server.UnsupportedMediaTypeStatusException;
|
||||
import org.springframework.web.util.WebUtils;
|
||||
|
||||
/**
|
||||
@@ -166,10 +166,13 @@ public abstract class RequestMappingInfoHandlerMapping extends AbstractHandlerMe
|
||||
/**
|
||||
* Iterate all RequestMappingInfos once again, look if any match by URL at
|
||||
* least and raise exceptions accordingly.
|
||||
* @throws HttpRequestMethodNotSupportedException if there are matches by URL
|
||||
* but not by HTTP method
|
||||
* @throws HttpMediaTypeNotAcceptableException if there are matches by URL
|
||||
* but not by consumable/producible media types
|
||||
* @throws MethodNotAllowedException for matches by URL but not by HTTP method
|
||||
* @throws UnsupportedMediaTypeStatusException if there are matches by URL
|
||||
* and HTTP method but not by consumable media types
|
||||
* @throws NotAcceptableStatusException if there are matches by URL and HTTP
|
||||
* method but not by producible media types
|
||||
* @throws BadRequestStatusException if there are matches by URL and HTTP
|
||||
* method but not by query parameter conditions
|
||||
*/
|
||||
@Override
|
||||
protected HandlerMethod handleNoMatch(Set<RequestMappingInfo> requestMappingInfos,
|
||||
@@ -205,7 +208,7 @@ public abstract class RequestMappingInfoHandlerMapping extends AbstractHandlerMe
|
||||
return new HandlerMethod(handler, HTTP_OPTIONS_HANDLE_METHOD);
|
||||
}
|
||||
else if (!allowedMethods.isEmpty()) {
|
||||
throw new HttpRequestMethodNotSupportedException(httpMethod.name(), allowedMethods);
|
||||
throw new MethodNotAllowedException(httpMethod.name(), allowedMethods);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -230,12 +233,12 @@ public abstract class RequestMappingInfoHandlerMapping extends AbstractHandlerMe
|
||||
contentType = request.getHeaders().getContentType();
|
||||
}
|
||||
catch (InvalidMediaTypeException ex) {
|
||||
throw new HttpMediaTypeNotSupportedException(ex.getMessage());
|
||||
throw new UnsupportedMediaTypeStatusException(ex.getMessage());
|
||||
}
|
||||
throw new HttpMediaTypeNotSupportedException(contentType, new ArrayList<>(consumableMediaTypes));
|
||||
throw new UnsupportedMediaTypeStatusException(contentType, new ArrayList<>(consumableMediaTypes));
|
||||
}
|
||||
else if (!producibleMediaTypes.isEmpty()) {
|
||||
throw new HttpMediaTypeNotAcceptableException(new ArrayList<>(producibleMediaTypes));
|
||||
throw new NotAcceptableStatusException(new ArrayList<>(producibleMediaTypes));
|
||||
}
|
||||
else {
|
||||
if (!CollectionUtils.isEmpty(paramConditions)) {
|
||||
@@ -243,7 +246,8 @@ public abstract class RequestMappingInfoHandlerMapping extends AbstractHandlerMe
|
||||
.collect(Collectors.toMap(Entry::getKey,
|
||||
entry -> entry.getValue().toArray(new String[entry.getValue().size()]))
|
||||
);
|
||||
throw new UnsatisfiedServletRequestParameterException(paramConditions, params);
|
||||
throw new BadRequestStatusException("Unsatisfied query parameter conditions: " +
|
||||
paramConditions + ", actual: " + params);
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
@@ -308,7 +312,7 @@ public abstract class RequestMappingInfoHandlerMapping extends AbstractHandlerMe
|
||||
}
|
||||
|
||||
private static Set<HttpMethod> initAllowedHttpMethods(Set<String> declaredMethods) {
|
||||
Set<HttpMethod> result = new LinkedHashSet<HttpMethod>(declaredMethods.size());
|
||||
Set<HttpMethod> result = new LinkedHashSet<>(declaredMethods.size());
|
||||
if (declaredMethods.isEmpty()) {
|
||||
for (HttpMethod method : HttpMethod.values()) {
|
||||
if (!HttpMethod.TRACE.equals(method)) {
|
||||
|
||||
@@ -42,11 +42,11 @@ import org.springframework.http.server.reactive.ServerHttpRequest;
|
||||
import org.springframework.http.server.reactive.ServerHttpResponse;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.MimeType;
|
||||
import org.springframework.web.HttpMediaTypeNotAcceptableException;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.method.HandlerMethod;
|
||||
import org.springframework.web.reactive.HandlerResult;
|
||||
import org.springframework.web.reactive.HandlerResultHandler;
|
||||
import org.springframework.web.server.NotAcceptableStatusException;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
|
||||
|
||||
@@ -170,7 +170,7 @@ public class ResponseBodyResultHandler implements HandlerResultHandler, Ordered
|
||||
}
|
||||
}
|
||||
if (compatibleMediaTypes.isEmpty()) {
|
||||
return Mono.error(new HttpMediaTypeNotAcceptableException(producibleMediaTypes));
|
||||
return Mono.error(new NotAcceptableStatusException(producibleMediaTypes));
|
||||
}
|
||||
|
||||
List<MediaType> mediaTypes = new ArrayList<>(compatibleMediaTypes);
|
||||
@@ -200,7 +200,7 @@ public class ResponseBodyResultHandler implements HandlerResultHandler, Ordered
|
||||
}
|
||||
}
|
||||
|
||||
return Mono.error(new HttpMediaTypeNotAcceptableException(this.allMediaTypes));
|
||||
return Mono.error(new NotAcceptableStatusException(this.allMediaTypes));
|
||||
}
|
||||
|
||||
private List<MediaType> getAcceptableMediaTypes(ServerHttpRequest request) {
|
||||
|
||||
Reference in New Issue
Block a user