Polishing

This commit is contained in:
Juergen Hoeller
2015-07-30 12:16:59 +02:00
parent 04348901f8
commit e8ef3654c6
28 changed files with 132 additions and 118 deletions

View File

@@ -244,7 +244,6 @@ public abstract class HttpRange {
this.suffixLength = suffixLength;
}
@Override
public long getRangeStart(long length) {
if (this.suffixLength < length) {

View File

@@ -117,6 +117,7 @@ class OkHttpClientHttpRequest extends AbstractBufferingAsyncClientHttpRequest
}
}
private static class OkHttpListenableFuture extends SettableListenableFuture<ClientHttpResponse> {
private final Call call;
@@ -124,12 +125,10 @@ class OkHttpClientHttpRequest extends AbstractBufferingAsyncClientHttpRequest
public OkHttpListenableFuture(Call call) {
this.call = call;
this.call.enqueue(new Callback() {
@Override
public void onResponse(Response response) {
set(new OkHttpClientHttpResponse(response));
}
@Override
public void onFailure(Request request, IOException ex) {
setException(ex);

View File

@@ -112,4 +112,5 @@ public class OkHttpClientHttpRequestFactory
this.client.getDispatcher().getExecutorService().shutdown();
}
}
}

View File

@@ -25,8 +25,7 @@ import org.springframework.http.HttpHeaders;
import org.springframework.util.Assert;
/**
* {@link org.springframework.http.client.ClientHttpResponse} implementation that uses
* OkHttp.
* {@link ClientHttpResponse} implementation based on OkHttp.
*
* @author Luciano Leggieri
* @author Arjen Poutsma
@@ -80,7 +79,8 @@ class OkHttpClientHttpResponse extends AbstractClientHttpResponse {
this.response.body().close();
}
catch (IOException ex) {
// Ignore
// ignore
}
}
}

View File

@@ -57,6 +57,7 @@ public abstract class AbstractGenericHttpMessageConverter<T> extends AbstractHtt
super(supportedMediaTypes);
}
@Override
public boolean canRead(Type type, Class<?> contextClass, MediaType mediaType) {
return canRead(contextClass, mediaType);
@@ -78,8 +79,7 @@ public abstract class AbstractGenericHttpMessageConverter<T> extends AbstractHtt
addDefaultHeaders(headers, t, contentType);
if (outputMessage instanceof StreamingHttpOutputMessage) {
StreamingHttpOutputMessage streamingOutputMessage =
(StreamingHttpOutputMessage) outputMessage;
StreamingHttpOutputMessage streamingOutputMessage = (StreamingHttpOutputMessage) outputMessage;
streamingOutputMessage.setBody(new StreamingHttpOutputMessage.Body() {
@Override
public void writeTo(final OutputStream outputStream) throws IOException {
@@ -106,6 +106,7 @@ public abstract class AbstractGenericHttpMessageConverter<T> extends AbstractHtt
@Override
protected void writeInternal(T t, HttpOutputMessage outputMessage)
throws IOException, HttpMessageNotWritableException {
writeInternal(t, null, outputMessage);
}

View File

@@ -201,9 +201,7 @@ public abstract class AbstractHttpMessageConverter<T> implements HttpMessageConv
* type was not provided, calls {@link #getContentLength}, and sets the corresponding headers
* @since 4.2
*/
protected void addDefaultHeaders(final HttpHeaders headers, final T t, MediaType contentType)
throws IOException{
protected void addDefaultHeaders(HttpHeaders headers, T t, MediaType contentType) throws IOException{
if (headers.getContentType() == null) {
MediaType contentTypeToUse = contentType;
if (contentType == null || contentType.isWildcardType() || contentType.isWildcardSubtype()) {

View File

@@ -88,18 +88,6 @@ public class UnsatisfiedServletRequestParameterException extends ServletRequestB
return sb.toString();
}
private static String requestParameterMapToString(Map<String, String[]> actualParams) {
StringBuilder result = new StringBuilder();
for (Iterator<Map.Entry<String, String[]>> it = actualParams.entrySet().iterator(); it.hasNext();) {
Map.Entry<String, String[]> entry = it.next();
result.append(entry.getKey()).append('=').append(ObjectUtils.nullSafeToString(entry.getValue()));
if (it.hasNext()) {
result.append(", ");
}
}
return result.toString();
}
/**
* Return the parameter conditions that have been violated or the first group
* in case of multiple groups.
@@ -126,4 +114,17 @@ public class UnsatisfiedServletRequestParameterException extends ServletRequestB
return this.actualParams;
}
private static String requestParameterMapToString(Map<String, String[]> actualParams) {
StringBuilder result = new StringBuilder();
for (Iterator<Map.Entry<String, String[]>> it = actualParams.entrySet().iterator(); it.hasNext();) {
Map.Entry<String, String[]> entry = it.next();
result.append(entry.getKey()).append('=').append(ObjectUtils.nullSafeToString(entry.getValue()));
if (it.hasNext()) {
result.append(", ");
}
}
return result.toString();
}
}

View File

@@ -116,7 +116,9 @@ public class AsyncRestTemplate extends AsyncHttpAccessor implements AsyncRestOpe
* @param asyncRequestFactory the asynchronous request factory
* @param syncRequestFactory the synchronous request factory
*/
public AsyncRestTemplate(AsyncClientHttpRequestFactory asyncRequestFactory, ClientHttpRequestFactory syncRequestFactory) {
public AsyncRestTemplate(
AsyncClientHttpRequestFactory asyncRequestFactory, ClientHttpRequestFactory syncRequestFactory) {
this(asyncRequestFactory, new RestTemplate(syncRequestFactory));
}
@@ -127,7 +129,7 @@ public class AsyncRestTemplate extends AsyncHttpAccessor implements AsyncRestOpe
* @param restTemplate the synchronous template to use
*/
public AsyncRestTemplate(AsyncClientHttpRequestFactory requestFactory, RestTemplate restTemplate) {
Assert.notNull(restTemplate, "'restTemplate' must not be null");
Assert.notNull(restTemplate, "RestTemplate must not be null");
this.syncTemplate = restTemplate;
setAsyncRequestFactory(requestFactory);
}
@@ -142,7 +144,9 @@ public class AsyncRestTemplate extends AsyncHttpAccessor implements AsyncRestOpe
this.syncTemplate.setErrorHandler(errorHandler);
}
/** Return the error handler. */
/**
* Return the error handler.
*/
public ResponseErrorHandler getErrorHandler() {
return this.syncTemplate.getErrorHandler();
}
@@ -180,7 +184,7 @@ public class AsyncRestTemplate extends AsyncHttpAccessor implements AsyncRestOpe
* Return the message body converters.
*/
public List<HttpMessageConverter<?>> getMessageConverters() {
return syncTemplate.getMessageConverters();
return this.syncTemplate.getMessageConverters();
}
@@ -232,6 +236,7 @@ public class AsyncRestTemplate extends AsyncHttpAccessor implements AsyncRestOpe
return execute(url, HttpMethod.HEAD, null, headersExtractor);
}
// POST
@Override

View File

@@ -190,7 +190,7 @@ public class RestTemplate extends InterceptingHttpAccessor implements RestOperat
* @since 3.2.7
*/
public RestTemplate(List<HttpMessageConverter<?>> messageConverters) {
Assert.notEmpty(messageConverters, "'messageConverters' must not be empty");
Assert.notEmpty(messageConverters, "At least one HttpMessageConverter required");
this.messageConverters.addAll(messageConverters);
}
@@ -200,7 +200,7 @@ public class RestTemplate extends InterceptingHttpAccessor implements RestOperat
* <p>These converters are used to convert from and to HTTP requests and responses.
*/
public void setMessageConverters(List<HttpMessageConverter<?>> messageConverters) {
Assert.notEmpty(messageConverters, "'messageConverters' must not be empty");
Assert.notEmpty(messageConverters, "At least one HttpMessageConverter required");
// Take getMessageConverters() List as-is when passed in here
if (this.messageConverters != messageConverters) {
this.messageConverters.clear();
@@ -220,7 +220,7 @@ public class RestTemplate extends InterceptingHttpAccessor implements RestOperat
* <p>By default, RestTemplate uses a {@link DefaultResponseErrorHandler}.
*/
public void setErrorHandler(ResponseErrorHandler errorHandler) {
Assert.notNull(errorHandler, "'errorHandler' must not be null");
Assert.notNull(errorHandler, "ResponseErrorHandler must not be null");
this.errorHandler = errorHandler;
}
@@ -237,7 +237,7 @@ public class RestTemplate extends InterceptingHttpAccessor implements RestOperat
* @param handler the URI template handler to use
*/
public void setUriTemplateHandler(UriTemplateHandler handler) {
Assert.notNull(handler, "'uriTemplateHandler' is required.");
Assert.notNull(handler, "UriTemplateHandler must not be null");
this.uriTemplateHandler = handler;
}

View File

@@ -74,6 +74,7 @@ public class CorsConfiguration {
this.maxAge = other.maxAge;
}
/**
* Combine the supplied {@code CorsConfiguration} with this one.
* <p>Properties of this configuration are overridden by any non-null
@@ -113,13 +114,23 @@ public class CorsConfiguration {
return combined;
}
/**
* Set the origins to allow, e.g. {@code "http://domain1.com"}.
* <p>The special value {@code "*"} allows all domains.
* <p>By default this is not set.
*/
public void setAllowedOrigins(List<String> allowedOrigins) {
this.allowedOrigins = (allowedOrigins == null ? null : new ArrayList<String>(allowedOrigins));
this.allowedOrigins = (allowedOrigins != null ? new ArrayList<String>(allowedOrigins) : null);
}
/**
* Return the configured origins to allow, possibly {@code null}.
* @see #addAllowedOrigin(String)
* @see #setAllowedOrigins(List)
*/
public List<String> getAllowedOrigins() {
return this.allowedOrigins;
}
/**
@@ -132,15 +143,6 @@ public class CorsConfiguration {
this.allowedOrigins.add(origin);
}
/**
* Return the configured origins to allow, possibly {@code null}.
* @see #addAllowedOrigin(String)
* @see #setAllowedOrigins(List)
*/
public List<String> getAllowedOrigins() {
return this.allowedOrigins;
}
/**
* Set the HTTP methods to allow, e.g. {@code "GET"}, {@code "POST"},
* {@code "PUT"}, etc.
@@ -149,7 +151,18 @@ public class CorsConfiguration {
* <p>By default this is not set.
*/
public void setAllowedMethods(List<String> allowedMethods) {
this.allowedMethods = (allowedMethods == null ? null : new ArrayList<String>(allowedMethods));
this.allowedMethods = (allowedMethods != null ? new ArrayList<String>(allowedMethods) : null);
}
/**
* Return the allowed HTTP methods, possibly {@code null} in which case
* only {@code "GET"} is allowed.
* @see #addAllowedMethod(HttpMethod)
* @see #addAllowedMethod(String)
* @see #setAllowedMethods(List)
*/
public List<String> getAllowedMethods() {
return this.allowedMethods;
}
/**
@@ -173,17 +186,6 @@ public class CorsConfiguration {
}
}
/**
* Return the allowed HTTP methods, possibly {@code null} in which case
* only {@code "GET"} is allowed.
* @see #addAllowedMethod(HttpMethod)
* @see #addAllowedMethod(String)
* @see #setAllowedMethods(List)
*/
public List<String> getAllowedMethods() {
return this.allowedMethods;
}
/**
* Set the list of headers that a pre-flight request can list as allowed
* for use during an actual request.
@@ -195,7 +197,16 @@ public class CorsConfiguration {
* <p>By default this is not set.
*/
public void setAllowedHeaders(List<String> allowedHeaders) {
this.allowedHeaders = (allowedHeaders == null ? null : new ArrayList<String>(allowedHeaders));
this.allowedHeaders = (allowedHeaders != null ? new ArrayList<String>(allowedHeaders) : null);
}
/**
* Return the allowed actual request headers, possibly {@code null}.
* @see #addAllowedHeader(String)
* @see #setAllowedHeaders(List)
*/
public List<String> getAllowedHeaders() {
return this.allowedHeaders;
}
/**
@@ -208,15 +219,6 @@ public class CorsConfiguration {
this.allowedHeaders.add(allowedHeader);
}
/**
* Return the allowed actual request headers, possibly {@code null}.
* @see #addAllowedHeader(String)
* @see #setAllowedHeaders(List)
*/
public List<String> getAllowedHeaders() {
return this.allowedHeaders;
}
/**
* Set the list of response headers other than simple headers (i.e.
* {@code Cache-Control}, {@code Content-Language}, {@code Content-Type},
@@ -232,6 +234,15 @@ public class CorsConfiguration {
this.exposedHeaders = (exposedHeaders == null ? null : new ArrayList<String>(exposedHeaders));
}
/**
* Return the configured response headers to expose, possibly {@code null}.
* @see #addExposedHeader(String)
* @see #setExposedHeaders(List)
*/
public List<String> getExposedHeaders() {
return this.exposedHeaders;
}
/**
* Add a response header to expose.
* <p>Note that {@code "*"} is not a valid exposed header value.
@@ -246,15 +257,6 @@ public class CorsConfiguration {
this.exposedHeaders.add(exposedHeader);
}
/**
* Return the configured response headers to expose, possibly {@code null}.
* @see #addExposedHeader(String)
* @see #setExposedHeaders(List)
*/
public List<String> getExposedHeaders() {
return this.exposedHeaders;
}
/**
* Whether user credentials are supported.
* <p>By default this is not set (i.e. user credentials are not supported).
@@ -285,9 +287,10 @@ public class CorsConfiguration {
* @see #setMaxAge(Long)
*/
public Long getMaxAge() {
return maxAge;
return this.maxAge;
}
/**
* Check the origin of the request against the configured allowed origins.
* @param requestOrigin the origin to check
@@ -303,9 +306,10 @@ public class CorsConfiguration {
}
if (this.allowedOrigins.contains(ALL)) {
if ((this.allowCredentials == null) || !this.allowCredentials.booleanValue()) {
if (this.allowCredentials != Boolean.TRUE) {
return ALL;
} else {
}
else {
return requestOrigin;
}
}
@@ -314,6 +318,7 @@ public class CorsConfiguration {
return requestOrigin;
}
}
return null;
}
@@ -329,9 +334,10 @@ public class CorsConfiguration {
if (requestMethod == null) {
return null;
}
List<String> allowedMethods = (this.allowedMethods == null ? new ArrayList<String>() : this.allowedMethods);
List<String> allowedMethods =
(this.allowedMethods != null ? this.allowedMethods : new ArrayList<String>());
if (allowedMethods.contains(ALL)) {
return Arrays.asList(requestMethod);
return Collections.singletonList(requestMethod);
}
if (allowedMethods.isEmpty()) {
allowedMethods.add(HttpMethod.GET.name());

View File

@@ -19,8 +19,8 @@ package org.springframework.web.cors;
import javax.servlet.http.HttpServletRequest;
/**
* Interface to be implemented by classes (usually HTTP request handlers) that provides
* a {@link CorsConfiguration} instance based on the provided request.
* Interface to be implemented by classes (usually HTTP request handlers) that
* provides a {@link CorsConfiguration} instance based on the provided request.
*
* @author Sebastien Deleuze
* @since 4.2

View File

@@ -39,11 +39,10 @@ public interface CorsProcessor {
/**
* Process a request given a {@code CorsConfiguration}.
*
* @param configuration the applicable CORS configuration, possibly {@code null}
* @param configuration the applicable CORS configuration (possibly {@code null})
* @param request the current request
* @param response the current response
* @return {@code false} if the request is rejected, else {@code true}.
* @return {@code false} if the request is rejected, {@code true} otherwise
*/
boolean processRequest(CorsConfiguration configuration, HttpServletRequest request,
HttpServletResponse response) throws IOException;

View File

@@ -41,8 +41,8 @@ public class CorsUtils {
* Returns {@code true} if the request is a valid CORS pre-flight one.
*/
public static boolean isPreFlightRequest(HttpServletRequest request) {
return (isCorsRequest(request) && request.getMethod().equals(HttpMethod.OPTIONS.name())
&& request.getHeader(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD) != null);
return (isCorsRequest(request) && request.getMethod().equals(HttpMethod.OPTIONS.name()) &&
request.getHeader(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD) != null);
}
}

View File

@@ -20,7 +20,6 @@ import java.io.IOException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@@ -59,8 +58,8 @@ public class DefaultCorsProcessor implements CorsProcessor {
@Override
public boolean processRequest(CorsConfiguration config, HttpServletRequest request,
HttpServletResponse response) throws IOException {
public boolean processRequest(CorsConfiguration config, HttpServletRequest request, HttpServletResponse response)
throws IOException {
if (!CorsUtils.isCorsRequest(request)) {
return true;

View File

@@ -27,19 +27,18 @@ import org.springframework.util.PathMatcher;
import org.springframework.web.util.UrlPathHelper;
/**
* Provide a per request {@link CorsConfiguration} instance based on a collection of
* {@link CorsConfiguration} mapped on path patterns.
* Provide a per request {@link CorsConfiguration} instance based on a
* collection of {@link CorsConfiguration} mapped on path patterns.
*
* <p>Exact path mapping URIs (such as {@code "/admin"}) are supported as
* well as Ant-style path patterns (such as {@code "/admin/**"}).
* <p>Exact path mapping URIs (such as {@code "/admin"}) are supported
* as well as Ant-style path patterns (such as {@code "/admin/**"}).
*
* @author Sebastien Deleuze
* @since 4.2
*/
public class UrlBasedCorsConfigurationSource implements CorsConfigurationSource {
private final Map<String, CorsConfiguration> corsConfigurations =
new LinkedHashMap<String, CorsConfiguration>();
private final Map<String, CorsConfiguration> corsConfigurations = new LinkedHashMap<String, CorsConfiguration>();
private PathMatcher pathMatcher = new AntPathMatcher();
@@ -120,6 +119,7 @@ public class UrlBasedCorsConfigurationSource implements CorsConfigurationSource
this.corsConfigurations.put(path, config);
}
@Override
public CorsConfiguration getCorsConfiguration(HttpServletRequest request) {
String lookupPath = this.urlPathHelper.getLookupPathForRequest(request);

View File

@@ -0,0 +1,5 @@
/**
* Support for CORS (Cross-Origin Resource Sharing),
* based on a common {@code CorsProcessor} strategy.
*/
package org.springframework.web.cors;

View File

@@ -19,7 +19,6 @@ package org.springframework.web.filter;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
@@ -144,8 +143,7 @@ public class ShallowEtagHeaderFilter extends OncePerRequestFilter {
protected boolean isEligibleForEtag(HttpServletRequest request, HttpServletResponse response,
int responseStatusCode, InputStream inputStream) {
if (responseStatusCode >= 200 && responseStatusCode < 300 &&
HttpMethod.GET.name().equals(request.getMethod())) {
if (responseStatusCode >= 200 && responseStatusCode < 300 && HttpMethod.GET.name().equals(request.getMethod())) {
String cacheControl = (responseGetHeaderAvailable ? response.getHeader(HEADER_CACHE_CONTROL) : null);
if (cacheControl == null || !cacheControl.contains(DIRECTIVE_NO_STORE)) {
return true;
@@ -173,6 +171,7 @@ public class ShallowEtagHeaderFilter extends OncePerRequestFilter {
return builder.toString();
}
/**
* This method can be used to disable the content caching response wrapper
* of the ShallowEtagHeaderFilter. This can be done before the start of HTTP
@@ -194,10 +193,7 @@ public class ShallowEtagHeaderFilter extends OncePerRequestFilter {
private final HttpServletRequest request;
public HttpStreamingAwareContentCachingResponseWrapper(HttpServletResponse response,
HttpServletRequest request) {
public HttpStreamingAwareContentCachingResponseWrapper(HttpServletResponse response, HttpServletRequest request) {
super(response);
this.request = request;
}

View File

@@ -108,11 +108,11 @@ public abstract class AbstractNamedValueMethodArgumentResolver implements Handle
}
catch (ConversionNotSupportedException ex) {
throw new MethodArgumentConversionNotSupportedException(arg, ex.getRequiredType(),
ex.getCause(), namedValueInfo.name, parameter);
namedValueInfo.name, parameter, ex.getCause());
}
catch (TypeMismatchException ex) {
throw new MethodArgumentTypeMismatchException(arg, ex.getRequiredType(),
ex.getCause(), namedValueInfo.name, parameter);
namedValueInfo.name, parameter, ex.getCause());
}
}

View File

@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.method.annotation;
import org.springframework.beans.ConversionNotSupportedException;
@@ -35,7 +36,7 @@ public class MethodArgumentConversionNotSupportedException extends ConversionNot
public MethodArgumentConversionNotSupportedException(Object value, Class<?> requiredType,
Throwable cause, String name, MethodParameter param) {
String name, MethodParameter param, Throwable cause) {
super(value, requiredType, cause);
this.name = name;

View File

@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.method.annotation;
import org.springframework.beans.TypeMismatchException;
@@ -35,7 +36,7 @@ public class MethodArgumentTypeMismatchException extends TypeMismatchException {
public MethodArgumentTypeMismatchException(Object value, Class<?> requiredType,
Throwable cause, String name, MethodParameter param) {
String name, MethodParameter param, Throwable cause) {
super(value, requiredType, cause);
this.name = name;

View File

@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.method.support;
import org.springframework.core.MethodParameter;
@@ -21,7 +22,7 @@ import org.springframework.core.MethodParameter;
* A {@link HandlerMethodReturnValueHandler} that handles return values that
* represent asynchronous computation. Such handlers need to be invoked with
* precedence over other handlers that might otherwise match the return value
* type -- e.g. a method that returns a Promise type that is also annotated with
* type: e.g. a method that returns a Promise type that is also annotated with
* {@code @ResponseBody}.
*
* <p>In {@link #handleReturnValue}, implementations of this class should create
@@ -32,7 +33,6 @@ import org.springframework.core.MethodParameter;
* DeferredResult<?> deferredResult = (DeferredResult<?>) returnValue;
* WebAsyncUtils.getAsyncManager(webRequest).startDeferredResultProcessing(deferredResult, mavContainer);
* </pre>
* the return value to a DeferredResult
*
* @author Rossen Stoyanchev
* @since 4.2

View File

@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.util;
import java.net.URI;
@@ -41,12 +42,10 @@ public class DefaultUriTemplateHandler implements UriTemplateHandler {
* have a scheme and host but may also contain a port and a partial path.
* Individual URI templates then may provide the remaining part of the URL
* including additional path, query and fragment.
*
* <p><strong>Note: </strong>Individual URI templates are expanded and
* encoded before being appended to the base URL. Therefore the base URL is
* expected to be fully expanded and encoded, which can be done with the help
* of {@link UriComponentsBuilder}.
*
* @param baseUrl the base URL.
*/
public void setBaseUrl(String baseUrl) {

View File

@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.util;
import java.net.URI;