summaryrefslogtreecommitdiff
path: root/spring-web/src/main/java/org
diff options
context:
space:
mode:
Diffstat (limited to 'spring-web/src/main/java/org')
-rw-r--r--spring-web/src/main/java/org/springframework/http/converter/AbstractHttpMessageConverter.java2
-rw-r--r--spring-web/src/main/java/org/springframework/http/converter/ByteArrayHttpMessageConverter.java8
-rw-r--r--spring-web/src/main/java/org/springframework/http/converter/FormHttpMessageConverter.java4
-rw-r--r--spring-web/src/main/java/org/springframework/http/converter/ObjectToStringHttpMessageConverter.java37
-rw-r--r--spring-web/src/main/java/org/springframework/http/converter/json/SpringHandlerInstantiator.java40
-rw-r--r--spring-web/src/main/java/org/springframework/http/converter/json/package-info.java2
-rw-r--r--spring-web/src/main/java/org/springframework/http/converter/protobuf/package-info.java5
-rw-r--r--spring-web/src/main/java/org/springframework/http/converter/support/AllEncompassingFormHttpMessageConverter.java4
-rw-r--r--spring-web/src/main/java/org/springframework/http/converter/support/package-info.java4
-rw-r--r--spring-web/src/main/java/org/springframework/http/converter/xml/package-info.java2
-rw-r--r--spring-web/src/main/java/org/springframework/http/server/ServletServerHttpRequest.java42
-rw-r--r--spring-web/src/main/java/org/springframework/web/accept/AbstractMappingContentNegotiationStrategy.java7
-rw-r--r--spring-web/src/main/java/org/springframework/web/accept/ContentNegotiationManager.java14
-rw-r--r--spring-web/src/main/java/org/springframework/web/accept/ContentNegotiationManagerFactoryBean.java38
-rw-r--r--spring-web/src/main/java/org/springframework/web/accept/ContentNegotiationStrategy.java6
-rw-r--r--spring-web/src/main/java/org/springframework/web/accept/FixedContentNegotiationStrategy.java5
-rw-r--r--spring-web/src/main/java/org/springframework/web/accept/HeaderContentNegotiationStrategy.java6
-rw-r--r--spring-web/src/main/java/org/springframework/web/accept/MappingMediaTypeFileExtensionResolver.java4
-rw-r--r--spring-web/src/main/java/org/springframework/web/accept/MediaTypeFileExtensionResolver.java7
-rw-r--r--spring-web/src/main/java/org/springframework/web/accept/ParameterContentNegotiationStrategy.java22
-rw-r--r--spring-web/src/main/java/org/springframework/web/accept/PathExtensionContentNegotiationStrategy.java5
-rw-r--r--spring-web/src/main/java/org/springframework/web/accept/ServletPathExtensionContentNegotiationStrategy.java14
-rw-r--r--spring-web/src/main/java/org/springframework/web/context/support/WebApplicationContextUtils.java4
-rw-r--r--spring-web/src/main/java/org/springframework/web/cors/CorsConfigurationSource.java3
-rw-r--r--spring-web/src/main/java/org/springframework/web/filter/AbstractRequestLoggingFilter.java7
-rw-r--r--spring-web/src/main/java/org/springframework/web/filter/CorsFilter.java22
-rw-r--r--spring-web/src/main/java/org/springframework/web/method/annotation/RequestParamMethodArgumentResolver.java4
-rw-r--r--spring-web/src/main/java/org/springframework/web/util/UriComponentsBuilder.java178
-rw-r--r--spring-web/src/main/java/org/springframework/web/util/WebUtils.java24
29 files changed, 284 insertions, 236 deletions
diff --git a/spring-web/src/main/java/org/springframework/http/converter/AbstractHttpMessageConverter.java b/spring-web/src/main/java/org/springframework/http/converter/AbstractHttpMessageConverter.java
index 42a91192..d63d2870 100644
--- a/spring-web/src/main/java/org/springframework/http/converter/AbstractHttpMessageConverter.java
+++ b/spring-web/src/main/java/org/springframework/http/converter/AbstractHttpMessageConverter.java
@@ -200,7 +200,7 @@ public abstract class AbstractHttpMessageConverter<T> implements HttpMessageConv
/**
* Add default headers to the output message.
* <p>This implementation delegates to {@link #getDefaultContentType(Object)} if a content
- * type was not provided, calls {@link #getContentLength}, and sets the corresponding headers
+ * type was not provided, calls {@link #getContentLength}, and sets the corresponding headers.
* @since 4.2
*/
protected void addDefaultHeaders(HttpHeaders headers, T t, MediaType contentType) throws IOException{
diff --git a/spring-web/src/main/java/org/springframework/http/converter/ByteArrayHttpMessageConverter.java b/spring-web/src/main/java/org/springframework/http/converter/ByteArrayHttpMessageConverter.java
index 87c003d7..12c95e14 100644
--- a/spring-web/src/main/java/org/springframework/http/converter/ByteArrayHttpMessageConverter.java
+++ b/spring-web/src/main/java/org/springframework/http/converter/ByteArrayHttpMessageConverter.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2014 the original author or authors.
+ * Copyright 2002-2016 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.
@@ -32,15 +32,19 @@ import org.springframework.util.StreamUtils;
* overridden by setting the {@link #setSupportedMediaTypes supportedMediaTypes} property.
*
* @author Arjen Poutsma
+ * @author Juergen Hoeller
* @since 3.0
*/
public class ByteArrayHttpMessageConverter extends AbstractHttpMessageConverter<byte[]> {
- /** Creates a new instance of the {@code ByteArrayHttpMessageConverter}. */
+ /**
+ * Create a new instance of the {@code ByteArrayHttpMessageConverter}.
+ */
public ByteArrayHttpMessageConverter() {
super(new MediaType("application", "octet-stream"), MediaType.ALL);
}
+
@Override
public boolean supports(Class<?> clazz) {
return byte[].class == clazz;
diff --git a/spring-web/src/main/java/org/springframework/http/converter/FormHttpMessageConverter.java b/spring-web/src/main/java/org/springframework/http/converter/FormHttpMessageConverter.java
index 44491be0..fa2d0e4a 100644
--- a/spring-web/src/main/java/org/springframework/http/converter/FormHttpMessageConverter.java
+++ b/spring-web/src/main/java/org/springframework/http/converter/FormHttpMessageConverter.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2015 the original author or authors.
+ * Copyright 2002-2016 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.
@@ -255,7 +255,7 @@ public class FormHttpMessageConverter implements HttpMessageConverter<MultiValue
Charset charset;
if (contentType != null) {
outputMessage.getHeaders().setContentType(contentType);
- charset = contentType.getCharSet() != null ? contentType.getCharSet() : this.charset;
+ charset = (contentType.getCharSet() != null ? contentType.getCharSet() : this.charset);
}
else {
outputMessage.getHeaders().setContentType(MediaType.APPLICATION_FORM_URLENCODED);
diff --git a/spring-web/src/main/java/org/springframework/http/converter/ObjectToStringHttpMessageConverter.java b/spring-web/src/main/java/org/springframework/http/converter/ObjectToStringHttpMessageConverter.java
index c1ef5c26..5fab4fec 100644
--- a/spring-web/src/main/java/org/springframework/http/converter/ObjectToStringHttpMessageConverter.java
+++ b/spring-web/src/main/java/org/springframework/http/converter/ObjectToStringHttpMessageConverter.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2012 the original author or authors.
+ * Copyright 2002-2016 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.
@@ -29,11 +29,12 @@ import org.springframework.util.Assert;
* An {@code HttpMessageConverter} that uses {@link StringHttpMessageConverter}
* for reading and writing content and a {@link ConversionService} for converting
* the String content to and from the target object type.
- * <p>
- * By default, this converter supports the media type {@code text/plain} only.
- * This can be overridden by setting the
- * {@link #setSupportedMediaTypes supportedMediaTypes} property.
- * Example of usage:
+ *
+ * <p>By default, this converter supports the media type {@code text/plain} only.
+ * This can be overridden through the {@link #setSupportedMediaTypes supportedMediaTypes}
+ * property.
+ *
+ * <p>A usage example:
*
* <pre class="code">
* &lt;bean class="org.springframework.http.converter.ObjectToStringHttpMessageConverter">
@@ -49,17 +50,15 @@ import org.springframework.util.Assert;
*/
public class ObjectToStringHttpMessageConverter extends AbstractHttpMessageConverter<Object> {
- private ConversionService conversionService;
+ private final ConversionService conversionService;
- private StringHttpMessageConverter stringHttpMessageConverter;
+ private final StringHttpMessageConverter stringHttpMessageConverter;
/**
* A constructor accepting a {@code ConversionService} to use to convert the
- * (String) message body to/from the target class type. This constructor
- * uses {@link StringHttpMessageConverter#DEFAULT_CHARSET} as the default
- * charset.
- *
+ * (String) message body to/from the target class type. This constructor uses
+ * {@link StringHttpMessageConverter#DEFAULT_CHARSET} as the default charset.
* @param conversionService the conversion service
*/
public ObjectToStringHttpMessageConverter(ConversionService conversionService) {
@@ -67,20 +66,19 @@ public class ObjectToStringHttpMessageConverter extends AbstractHttpMessageConve
}
/**
- * A constructor accepting a {@code ConversionService} as well as a default
- * charset.
- *
+ * A constructor accepting a {@code ConversionService} as well as a default charset.
* @param conversionService the conversion service
* @param defaultCharset the default charset
*/
public ObjectToStringHttpMessageConverter(ConversionService conversionService, Charset defaultCharset) {
super(new MediaType("text", "plain", defaultCharset));
- Assert.notNull(conversionService, "conversionService is required");
+ Assert.notNull(conversionService, "ConversionService is required");
this.conversionService = conversionService;
this.stringHttpMessageConverter = new StringHttpMessageConverter(defaultCharset);
}
+
/**
* Indicates whether the {@code Accept-Charset} should be written to any outgoing request.
* <p>Default is {@code true}.
@@ -89,6 +87,7 @@ public class ObjectToStringHttpMessageConverter extends AbstractHttpMessageConve
this.stringHttpMessageConverter.setWriteAcceptCharset(writeAcceptCharset);
}
+
@Override
public boolean canRead(Class<?> clazz, MediaType mediaType) {
return this.conversionService.canConvert(String.class, clazz) && canRead(mediaType);
@@ -106,15 +105,15 @@ public class ObjectToStringHttpMessageConverter extends AbstractHttpMessageConve
}
@Override
- protected Object readInternal(Class<? extends Object> clazz, HttpInputMessage inputMessage) throws IOException {
+ protected Object readInternal(Class<?> clazz, HttpInputMessage inputMessage) throws IOException {
String value = this.stringHttpMessageConverter.readInternal(String.class, inputMessage);
return this.conversionService.convert(value, clazz);
}
@Override
protected void writeInternal(Object obj, HttpOutputMessage outputMessage) throws IOException {
- String s = this.conversionService.convert(obj, String.class);
- this.stringHttpMessageConverter.writeInternal(s, outputMessage);
+ String value = this.conversionService.convert(obj, String.class);
+ this.stringHttpMessageConverter.writeInternal(value, outputMessage);
}
@Override
diff --git a/spring-web/src/main/java/org/springframework/http/converter/json/SpringHandlerInstantiator.java b/spring-web/src/main/java/org/springframework/http/converter/json/SpringHandlerInstantiator.java
index ef7446ae..f208c32a 100644
--- a/spring-web/src/main/java/org/springframework/http/converter/json/SpringHandlerInstantiator.java
+++ b/spring-web/src/main/java/org/springframework/http/converter/json/SpringHandlerInstantiator.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2014 the original author or authors.
+ * Copyright 2002-2016 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.
@@ -32,14 +32,15 @@ import org.springframework.context.ApplicationContext;
import org.springframework.util.Assert;
/**
- * Eventually get Jackson handler ({@link JsonSerializer}, {@link JsonDeserializer},
- * {@link KeyDeserializer}, {@link TypeResolverBuilder}, {@link TypeIdResolver}) beans by
- * type from Spring {@link ApplicationContext}. If no bean is found, the default behavior
- * happen (calling no-argument constructor via reflection).
+ * Allows for creating Jackson ({@link JsonSerializer}, {@link JsonDeserializer},
+ * {@link KeyDeserializer}, {@link TypeResolverBuilder}, {@link TypeIdResolver})
+ * beans with autowiring against a Spring {@link ApplicationContext}.
*
- * @since 4.1.3
* @author Sebastien Deleuze
+ * @author Juergen Hoeller
+ * @since 4.1.3
* @see Jackson2ObjectMapperBuilder#handlerInstantiator(HandlerInstantiator)
+ * @see ApplicationContext#getAutowireCapableBeanFactory()
* @see HandlerInstantiator
*/
public class SpringHandlerInstantiator extends HandlerInstantiator {
@@ -56,33 +57,30 @@ public class SpringHandlerInstantiator extends HandlerInstantiator {
this.beanFactory = beanFactory;
}
+
@Override
- public JsonSerializer<?> serializerInstance(SerializationConfig config,
- Annotated annotated, Class<?> keyDeserClass) {
- return (JsonSerializer<?>) this.beanFactory.createBean(keyDeserClass);
+ public JsonDeserializer<?> deserializerInstance(DeserializationConfig config, Annotated annotated, Class<?> implClass) {
+ return (JsonDeserializer<?>) this.beanFactory.createBean(implClass);
}
@Override
- public JsonDeserializer<?> deserializerInstance(DeserializationConfig config,
- Annotated annotated, Class<?> deserClass) {
- return (JsonDeserializer<?>) this.beanFactory.createBean(deserClass);
+ public KeyDeserializer keyDeserializerInstance(DeserializationConfig config, Annotated annotated, Class<?> implClass) {
+ return (KeyDeserializer) this.beanFactory.createBean(implClass);
}
@Override
- public KeyDeserializer keyDeserializerInstance(DeserializationConfig config,
- Annotated annotated, Class<?> serClass) {
- return (KeyDeserializer) this.beanFactory.createBean(serClass);
+ public JsonSerializer<?> serializerInstance(SerializationConfig config, Annotated annotated, Class<?> implClass) {
+ return (JsonSerializer<?>) this.beanFactory.createBean(implClass);
}
@Override
- public TypeResolverBuilder<?> typeResolverBuilderInstance(MapperConfig<?> config,
- Annotated annotated, Class<?> resolverClass) {
- return (TypeResolverBuilder<?>) this.beanFactory.createBean(resolverClass);
+ public TypeResolverBuilder<?> typeResolverBuilderInstance(MapperConfig<?> config, Annotated annotated, Class<?> implClass) {
+ return (TypeResolverBuilder<?>) this.beanFactory.createBean(implClass);
}
@Override
- public TypeIdResolver typeIdResolverInstance(MapperConfig<?> config,
- Annotated annotated, Class<?> resolverClass) {
- return (TypeIdResolver) this.beanFactory.createBean(resolverClass);
+ public TypeIdResolver typeIdResolverInstance(MapperConfig<?> config, Annotated annotated, Class<?> implClass) {
+ return (TypeIdResolver) this.beanFactory.createBean(implClass);
}
+
}
diff --git a/spring-web/src/main/java/org/springframework/http/converter/json/package-info.java b/spring-web/src/main/java/org/springframework/http/converter/json/package-info.java
index c786a6d2..886aa944 100644
--- a/spring-web/src/main/java/org/springframework/http/converter/json/package-info.java
+++ b/spring-web/src/main/java/org/springframework/http/converter/json/package-info.java
@@ -1,4 +1,4 @@
/**
- * Provides an HttpMessageConverter implementations for handling JSON.
+ * Provides HttpMessageConverter implementations for handling JSON.
*/
package org.springframework.http.converter.json;
diff --git a/spring-web/src/main/java/org/springframework/http/converter/protobuf/package-info.java b/spring-web/src/main/java/org/springframework/http/converter/protobuf/package-info.java
new file mode 100644
index 00000000..3c73a272
--- /dev/null
+++ b/spring-web/src/main/java/org/springframework/http/converter/protobuf/package-info.java
@@ -0,0 +1,5 @@
+/**
+ * Provides an HttpMessageConverter implementation for handling
+ * <a href="https://developers.google.com/protocol-buffers/">Google Protocol Buffers</a>.
+ */
+package org.springframework.http.converter.protobuf;
diff --git a/spring-web/src/main/java/org/springframework/http/converter/support/AllEncompassingFormHttpMessageConverter.java b/spring-web/src/main/java/org/springframework/http/converter/support/AllEncompassingFormHttpMessageConverter.java
index d93e6ff1..2edcbb8f 100644
--- a/spring-web/src/main/java/org/springframework/http/converter/support/AllEncompassingFormHttpMessageConverter.java
+++ b/spring-web/src/main/java/org/springframework/http/converter/support/AllEncompassingFormHttpMessageConverter.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2015 the original author or authors.
+ * Copyright 2002-2016 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.
@@ -53,7 +53,7 @@ public class AllEncompassingFormHttpMessageConverter extends FormHttpMessageConv
public AllEncompassingFormHttpMessageConverter() {
addPartConverter(new SourceHttpMessageConverter<Source>());
- if (jaxb2Present && !jackson2Present) {
+ if (jaxb2Present && !jackson2XmlPresent) {
addPartConverter(new Jaxb2RootElementHttpMessageConverter());
}
diff --git a/spring-web/src/main/java/org/springframework/http/converter/support/package-info.java b/spring-web/src/main/java/org/springframework/http/converter/support/package-info.java
new file mode 100644
index 00000000..eaaf8204
--- /dev/null
+++ b/spring-web/src/main/java/org/springframework/http/converter/support/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * Provides a comprehensive HttpMessageConverter variant for form handling.
+ */
+package org.springframework.http.converter.support;
diff --git a/spring-web/src/main/java/org/springframework/http/converter/xml/package-info.java b/spring-web/src/main/java/org/springframework/http/converter/xml/package-info.java
index ef2c3c95..a889b351 100644
--- a/spring-web/src/main/java/org/springframework/http/converter/xml/package-info.java
+++ b/spring-web/src/main/java/org/springframework/http/converter/xml/package-info.java
@@ -1,4 +1,4 @@
/**
- * Provides an HttpMessageConverter implementations for handling XML.
+ * Provides HttpMessageConverter implementations for handling XML.
*/
package org.springframework.http.converter.xml;
diff --git a/spring-web/src/main/java/org/springframework/http/server/ServletServerHttpRequest.java b/spring-web/src/main/java/org/springframework/http/server/ServletServerHttpRequest.java
index 6fda91d2..4a8f342a 100644
--- a/spring-web/src/main/java/org/springframework/http/server/ServletServerHttpRequest.java
+++ b/spring-web/src/main/java/org/springframework/http/server/ServletServerHttpRequest.java
@@ -37,6 +37,7 @@ import javax.servlet.http.HttpServletRequest;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
+import org.springframework.http.InvalidMediaTypeException;
import org.springframework.http.MediaType;
import org.springframework.util.Assert;
import org.springframework.util.LinkedCaseInsensitiveMap;
@@ -104,6 +105,7 @@ public class ServletServerHttpRequest implements ServerHttpRequest {
public HttpHeaders getHeaders() {
if (this.headers == null) {
this.headers = new HttpHeaders();
+
for (Enumeration<?> headerNames = this.servletRequest.getHeaderNames(); headerNames.hasMoreElements();) {
String headerName = (String) headerNames.nextElement();
for (Enumeration<?> headerValues = this.servletRequest.getHeaders(headerName);
@@ -112,26 +114,33 @@ public class ServletServerHttpRequest implements ServerHttpRequest {
this.headers.add(headerName, headerValue);
}
}
+
// HttpServletRequest exposes some headers as properties: we should include those if not already present
- MediaType contentType = this.headers.getContentType();
- if (contentType == null) {
- String requestContentType = this.servletRequest.getContentType();
- if (StringUtils.hasLength(requestContentType)) {
- contentType = MediaType.parseMediaType(requestContentType);
- this.headers.setContentType(contentType);
+ try {
+ MediaType contentType = this.headers.getContentType();
+ if (contentType == null) {
+ String requestContentType = this.servletRequest.getContentType();
+ if (StringUtils.hasLength(requestContentType)) {
+ contentType = MediaType.parseMediaType(requestContentType);
+ this.headers.setContentType(contentType);
+ }
}
- }
- if (contentType != null && contentType.getCharSet() == null) {
- String requestEncoding = this.servletRequest.getCharacterEncoding();
- if (StringUtils.hasLength(requestEncoding)) {
- Charset charSet = Charset.forName(requestEncoding);
- Map<String, String> params = new LinkedCaseInsensitiveMap<String>();
- params.putAll(contentType.getParameters());
- params.put("charset", charSet.toString());
- MediaType newContentType = new MediaType(contentType.getType(), contentType.getSubtype(), params);
- this.headers.setContentType(newContentType);
+ if (contentType != null && contentType.getCharSet() == null) {
+ String requestEncoding = this.servletRequest.getCharacterEncoding();
+ if (StringUtils.hasLength(requestEncoding)) {
+ Charset charSet = Charset.forName(requestEncoding);
+ Map<String, String> params = new LinkedCaseInsensitiveMap<String>();
+ params.putAll(contentType.getParameters());
+ params.put("charset", charSet.toString());
+ MediaType newContentType = new MediaType(contentType.getType(), contentType.getSubtype(), params);
+ this.headers.setContentType(newContentType);
+ }
}
}
+ catch (InvalidMediaTypeException ex) {
+ // Ignore: simply not exposing an invalid content type in HttpHeaders...
+ }
+
if (this.headers.getContentLength() < 0) {
int requestContentLength = this.servletRequest.getContentLength();
if (requestContentLength != -1) {
@@ -139,6 +148,7 @@ public class ServletServerHttpRequest implements ServerHttpRequest {
}
}
}
+
return this.headers;
}
diff --git a/spring-web/src/main/java/org/springframework/web/accept/AbstractMappingContentNegotiationStrategy.java b/spring-web/src/main/java/org/springframework/web/accept/AbstractMappingContentNegotiationStrategy.java
index 0568b904..ee83d31f 100644
--- a/spring-web/src/main/java/org/springframework/web/accept/AbstractMappingContentNegotiationStrategy.java
+++ b/spring-web/src/main/java/org/springframework/web/accept/AbstractMappingContentNegotiationStrategy.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2015 the original author or authors.
+ * Copyright 2002-2016 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.
@@ -43,11 +43,9 @@ import org.springframework.web.context.request.NativeWebRequest;
* @author Rossen Stoyanchev
* @since 3.2
*/
-public abstract class AbstractMappingContentNegotiationStrategy
- extends MappingMediaTypeFileExtensionResolver
+public abstract class AbstractMappingContentNegotiationStrategy extends MappingMediaTypeFileExtensionResolver
implements ContentNegotiationStrategy {
-
/**
* Create an instance with the given map of file extensions and media types.
*/
@@ -86,6 +84,7 @@ public abstract class AbstractMappingContentNegotiationStrategy
return Collections.emptyList();
}
+
/**
* Extract a key from the request to use to look up media types.
* @return the lookup key or {@code null}.
diff --git a/spring-web/src/main/java/org/springframework/web/accept/ContentNegotiationManager.java b/spring-web/src/main/java/org/springframework/web/accept/ContentNegotiationManager.java
index 4450ad10..3f6efab3 100644
--- a/spring-web/src/main/java/org/springframework/web/accept/ContentNegotiationManager.java
+++ b/spring-web/src/main/java/org/springframework/web/accept/ContentNegotiationManager.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2015 the original author or authors.
+ * Copyright 2002-2016 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.
@@ -41,18 +41,14 @@ import org.springframework.web.context.request.NativeWebRequest;
* @author Rossen Stoyanchev
* @since 3.2
*/
-public class ContentNegotiationManager implements ContentNegotiationStrategy,
- MediaTypeFileExtensionResolver {
+public class ContentNegotiationManager implements ContentNegotiationStrategy, MediaTypeFileExtensionResolver {
- private static final List<MediaType> MEDIA_TYPE_ALL =
- Collections.<MediaType>singletonList(MediaType.ALL);
+ private static final List<MediaType> MEDIA_TYPE_ALL = Collections.<MediaType>singletonList(MediaType.ALL);
- private final List<ContentNegotiationStrategy> strategies =
- new ArrayList<ContentNegotiationStrategy>();
+ private final List<ContentNegotiationStrategy> strategies = new ArrayList<ContentNegotiationStrategy>();
- private final Set<MediaTypeFileExtensionResolver> resolvers =
- new LinkedHashSet<MediaTypeFileExtensionResolver>();
+ private final Set<MediaTypeFileExtensionResolver> resolvers = new LinkedHashSet<MediaTypeFileExtensionResolver>();
/**
diff --git a/spring-web/src/main/java/org/springframework/web/accept/ContentNegotiationManagerFactoryBean.java b/spring-web/src/main/java/org/springframework/web/accept/ContentNegotiationManagerFactoryBean.java
index b035b079..dfcd8499 100644
--- a/spring-web/src/main/java/org/springframework/web/accept/ContentNegotiationManagerFactoryBean.java
+++ b/spring-web/src/main/java/org/springframework/web/accept/ContentNegotiationManagerFactoryBean.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2015 the original author or authors.
+ * Copyright 2002-2016 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.
@@ -40,34 +40,34 @@ import org.springframework.web.context.ServletContextAware;
*
* <table>
* <tr>
- * <th>Property Setter</th>
- * <th>Underlying Strategy</th>
- * <th>Default Setting</th>
+ * <th>Property Setter</th>
+ * <th>Underlying Strategy</th>
+ * <th>Default Setting</th>
* </tr>
* <tr>
- * <td>{@link #setFavorPathExtension}</td>
- * <td>{@link PathExtensionContentNegotiationStrategy Path Extension strategy}</td>
- * <td>On</td>
+ * <td>{@link #setFavorPathExtension}</td>
+ * <td>{@link PathExtensionContentNegotiationStrategy Path Extension strategy}</td>
+ * <td>On</td>
* </tr>
* <tr>
- * <td>{@link #setFavorParameter favorParameter}</td>
- * <td>{@link ParameterContentNegotiationStrategy Parameter strategy}</td>
- * <td>Off</td>
+ * <td>{@link #setFavorParameter favorParameter}</td>
+ * <td>{@link ParameterContentNegotiationStrategy Parameter strategy}</td>
+ * <td>Off</td>
* </tr>
* <tr>
- * <td>{@link #setIgnoreAcceptHeader ignoreAcceptHeader}</td>
- * <td>{@link HeaderContentNegotiationStrategy Header strategy}</td>
- * <td>On</td>
+ * <td>{@link #setIgnoreAcceptHeader ignoreAcceptHeader}</td>
+ * <td>{@link HeaderContentNegotiationStrategy Header strategy}</td>
+ * <td>On</td>
* </tr>
* <tr>
- * <td>{@link #setDefaultContentType defaultContentType}</td>
- * <td>{@link FixedContentNegotiationStrategy Fixed content strategy}</td>
- * <td>Not set</td>
+ * <td>{@link #setDefaultContentType defaultContentType}</td>
+ * <td>{@link FixedContentNegotiationStrategy Fixed content strategy}</td>
+ * <td>Not set</td>
* </tr>
* <tr>
- * <td>{@link #setDefaultContentTypeStrategy defaultContentTypeStrategy}</td>
- * <td>{@link ContentNegotiationStrategy}</td>
- * <td>Not set</td>
+ * <td>{@link #setDefaultContentTypeStrategy defaultContentTypeStrategy}</td>
+ * <td>{@link ContentNegotiationStrategy}</td>
+ * <td>Not set</td>
* </tr>
* </table>
*
diff --git a/spring-web/src/main/java/org/springframework/web/accept/ContentNegotiationStrategy.java b/spring-web/src/main/java/org/springframework/web/accept/ContentNegotiationStrategy.java
index 127f90ce..586485a7 100644
--- a/spring-web/src/main/java/org/springframework/web/accept/ContentNegotiationStrategy.java
+++ b/spring-web/src/main/java/org/springframework/web/accept/ContentNegotiationStrategy.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2015 the original author or authors.
+ * Copyright 2002-2016 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.
@@ -33,10 +33,8 @@ public interface ContentNegotiationStrategy {
/**
* Resolve the given request to a list of media types. The returned list is
* ordered by specificity first and by quality parameter second.
- *
* @param webRequest the current request
- * @return the requested media types or an empty list, never {@code null}
- *
+ * @return the requested media types or an empty list (never {@code null})
* @throws HttpMediaTypeNotAcceptableException if the requested media
* types cannot be parsed
*/
diff --git a/spring-web/src/main/java/org/springframework/web/accept/FixedContentNegotiationStrategy.java b/spring-web/src/main/java/org/springframework/web/accept/FixedContentNegotiationStrategy.java
index 547ccef7..50478683 100644
--- a/spring-web/src/main/java/org/springframework/web/accept/FixedContentNegotiationStrategy.java
+++ b/spring-web/src/main/java/org/springframework/web/accept/FixedContentNegotiationStrategy.java
@@ -33,8 +33,7 @@ import org.springframework.web.context.request.NativeWebRequest;
*/
public class FixedContentNegotiationStrategy implements ContentNegotiationStrategy {
- private static final Log logger = LogFactory.getLog(
- FixedContentNegotiationStrategy.class);
+ private static final Log logger = LogFactory.getLog(FixedContentNegotiationStrategy.class);
private final List<MediaType> contentType;
@@ -50,7 +49,7 @@ public class FixedContentNegotiationStrategy implements ContentNegotiationStrate
@Override
public List<MediaType> resolveMediaTypes(NativeWebRequest request) {
if (logger.isDebugEnabled()) {
- logger.debug("Requested media types is " + this.contentType + ".");
+ logger.debug("Requested media types: " + this.contentType);
}
return this.contentType;
}
diff --git a/spring-web/src/main/java/org/springframework/web/accept/HeaderContentNegotiationStrategy.java b/spring-web/src/main/java/org/springframework/web/accept/HeaderContentNegotiationStrategy.java
index bcefd727..2642853d 100644
--- a/spring-web/src/main/java/org/springframework/web/accept/HeaderContentNegotiationStrategy.java
+++ b/spring-web/src/main/java/org/springframework/web/accept/HeaderContentNegotiationStrategy.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2015 the original author or authors.
+ * Copyright 2002-2016 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.
@@ -34,11 +34,9 @@ import org.springframework.web.context.request.NativeWebRequest;
*/
public class HeaderContentNegotiationStrategy implements ContentNegotiationStrategy {
-
/**
* {@inheritDoc}
- * @throws HttpMediaTypeNotAcceptableException if the 'Accept' header
- * cannot be parsed.
+ * @throws HttpMediaTypeNotAcceptableException if the 'Accept' header cannot be parsed
*/
@Override
public List<MediaType> resolveMediaTypes(NativeWebRequest request)
diff --git a/spring-web/src/main/java/org/springframework/web/accept/MappingMediaTypeFileExtensionResolver.java b/spring-web/src/main/java/org/springframework/web/accept/MappingMediaTypeFileExtensionResolver.java
index 6c2c8c7d..49c38d6d 100644
--- a/spring-web/src/main/java/org/springframework/web/accept/MappingMediaTypeFileExtensionResolver.java
+++ b/spring-web/src/main/java/org/springframework/web/accept/MappingMediaTypeFileExtensionResolver.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2015 the original author or authors.
+ * Copyright 2002-2016 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.
@@ -35,7 +35,7 @@ import org.springframework.util.MultiValueMap;
* lookups between file extensions and MediaTypes in both directions.
*
* <p>Initially created with a map of file extensions and media types.
- * Subsequently sub-classes can use {@link #addMapping} to add more mappings.
+ * Subsequently subclasses can use {@link #addMapping} to add more mappings.
*
* @author Rossen Stoyanchev
* @since 3.2
diff --git a/spring-web/src/main/java/org/springframework/web/accept/MediaTypeFileExtensionResolver.java b/spring-web/src/main/java/org/springframework/web/accept/MediaTypeFileExtensionResolver.java
index c063e5c5..49a7fcd9 100644
--- a/spring-web/src/main/java/org/springframework/web/accept/MediaTypeFileExtensionResolver.java
+++ b/spring-web/src/main/java/org/springframework/web/accept/MediaTypeFileExtensionResolver.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2015 the original author or authors.
+ * Copyright 2002-2016 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.
@@ -31,15 +31,14 @@ public interface MediaTypeFileExtensionResolver {
/**
* Resolve the given media type to a list of path extensions.
- *
* @param mediaType the media type to resolve
- * @return a list of extensions or an empty list, never {@code null}
+ * @return a list of extensions or an empty list (never {@code null})
*/
List<String> resolveFileExtensions(MediaType mediaType);
/**
* Return all registered file extensions.
- * @return a list of extensions or an empty list, never {@code null}
+ * @return a list of extensions or an empty list (never {@code null})
*/
List<String> getAllFileExtensions();
diff --git a/spring-web/src/main/java/org/springframework/web/accept/ParameterContentNegotiationStrategy.java b/spring-web/src/main/java/org/springframework/web/accept/ParameterContentNegotiationStrategy.java
index a2520d27..f6a9cb4e 100644
--- a/spring-web/src/main/java/org/springframework/web/accept/ParameterContentNegotiationStrategy.java
+++ b/spring-web/src/main/java/org/springframework/web/accept/ParameterContentNegotiationStrategy.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2015 the original author or authors.
+ * Copyright 2002-2016 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.
@@ -27,18 +27,15 @@ import org.springframework.web.HttpMediaTypeNotAcceptableException;
import org.springframework.web.context.request.NativeWebRequest;
/**
- * A {@code ContentNegotiationStrategy} that resolves a query parameter to a
- * key to be used to look up a media type. The default parameter name is
- * {@code format}.
- *s
+ * A {@code ContentNegotiationStrategy} that resolves a query parameter to a key
+ * to be used to look up a media type. The default parameter name is {@code format}.
+ *
* @author Rossen Stoyanchev
* @since 3.2
*/
-public class ParameterContentNegotiationStrategy
- extends AbstractMappingContentNegotiationStrategy {
+public class ParameterContentNegotiationStrategy extends AbstractMappingContentNegotiationStrategy {
- private static final Log logger = LogFactory.getLog(
- ParameterContentNegotiationStrategy.class);
+ private static final Log logger = LogFactory.getLog(ParameterContentNegotiationStrategy.class);
private String parameterName = "format";
@@ -56,7 +53,7 @@ public class ParameterContentNegotiationStrategy
* <p>By default this is set to {@code "format"}.
*/
public void setParameterName(String parameterName) {
- Assert.notNull(parameterName, "parameterName is required");
+ Assert.notNull(parameterName, "'parameterName' is required");
this.parameterName = parameterName;
}
@@ -64,6 +61,7 @@ public class ParameterContentNegotiationStrategy
return this.parameterName;
}
+
@Override
protected String getMediaTypeKey(NativeWebRequest request) {
return request.getParameter(getParameterName());
@@ -72,8 +70,8 @@ public class ParameterContentNegotiationStrategy
@Override
protected void handleMatch(String mediaTypeKey, MediaType mediaType) {
if (logger.isDebugEnabled()) {
- logger.debug("Requested media type is '" + mediaType +
- "' based on '" + getParameterName() + "'='" + mediaTypeKey + "'.");
+ logger.debug("Requested media type: '" + mediaType + "' based on '" +
+ getParameterName() + "'='" + mediaTypeKey + "'");
}
}
diff --git a/spring-web/src/main/java/org/springframework/web/accept/PathExtensionContentNegotiationStrategy.java b/spring-web/src/main/java/org/springframework/web/accept/PathExtensionContentNegotiationStrategy.java
index 9b19c271..9f0c2672 100644
--- a/spring-web/src/main/java/org/springframework/web/accept/PathExtensionContentNegotiationStrategy.java
+++ b/spring-web/src/main/java/org/springframework/web/accept/PathExtensionContentNegotiationStrategy.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2015 the original author or authors.
+ * Copyright 2002-2016 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.
@@ -56,8 +56,7 @@ public class PathExtensionContentNegotiationStrategy
private static final Log logger = LogFactory.getLog(PathExtensionContentNegotiationStrategy.class);
- private static final boolean JAF_PRESENT = ClassUtils.isPresent(
- "javax.activation.FileTypeMap",
+ private static final boolean JAF_PRESENT = ClassUtils.isPresent("javax.activation.FileTypeMap",
PathExtensionContentNegotiationStrategy.class.getClassLoader());
private static final UrlPathHelper PATH_HELPER = new UrlPathHelper();
diff --git a/spring-web/src/main/java/org/springframework/web/accept/ServletPathExtensionContentNegotiationStrategy.java b/spring-web/src/main/java/org/springframework/web/accept/ServletPathExtensionContentNegotiationStrategy.java
index 20338710..615568b4 100644
--- a/spring-web/src/main/java/org/springframework/web/accept/ServletPathExtensionContentNegotiationStrategy.java
+++ b/spring-web/src/main/java/org/springframework/web/accept/ServletPathExtensionContentNegotiationStrategy.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2015 the original author or authors.
+ * Copyright 2002-2016 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.
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
package org.springframework.web.accept;
import java.util.Map;
@@ -31,8 +32,7 @@ import org.springframework.web.context.request.NativeWebRequest;
* @author Rossen Stoyanchev
* @since 3.2
*/
-public class ServletPathExtensionContentNegotiationStrategy
- extends PathExtensionContentNegotiationStrategy {
+public class ServletPathExtensionContentNegotiationStrategy extends PathExtensionContentNegotiationStrategy {
private final ServletContext servletContext;
@@ -40,12 +40,12 @@ public class ServletPathExtensionContentNegotiationStrategy
/**
* Create an instance with the given extension-to-MediaType lookup.
*/
- public ServletPathExtensionContentNegotiationStrategy(ServletContext context,
- Map<String, MediaType> mediaTypes) {
+ public ServletPathExtensionContentNegotiationStrategy(
+ ServletContext servletContext, Map<String, MediaType> mediaTypes) {
super(mediaTypes);
- Assert.notNull(context, "ServletContext is required!");
- this.servletContext = context;
+ Assert.notNull(servletContext, "ServletContext is required");
+ this.servletContext = servletContext;
}
/**
diff --git a/spring-web/src/main/java/org/springframework/web/context/support/WebApplicationContextUtils.java b/spring-web/src/main/java/org/springframework/web/context/support/WebApplicationContextUtils.java
index ae75fbe4..26838d39 100644
--- a/spring-web/src/main/java/org/springframework/web/context/support/WebApplicationContextUtils.java
+++ b/spring-web/src/main/java/org/springframework/web/context/support/WebApplicationContextUtils.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2014 the original author or authors.
+ * Copyright 2002-2016 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.
@@ -288,7 +288,7 @@ public abstract class WebApplicationContextUtils {
public static void initServletPropertySources(
MutablePropertySources propertySources, ServletContext servletContext, ServletConfig servletConfig) {
- Assert.notNull(propertySources, "propertySources must not be null");
+ Assert.notNull(propertySources, "'propertySources' must not be null");
if (servletContext != null && propertySources.contains(StandardServletEnvironment.SERVLET_CONTEXT_PROPERTY_SOURCE_NAME) &&
propertySources.get(StandardServletEnvironment.SERVLET_CONTEXT_PROPERTY_SOURCE_NAME) instanceof StubPropertySource) {
propertySources.replace(StandardServletEnvironment.SERVLET_CONTEXT_PROPERTY_SOURCE_NAME,
diff --git a/spring-web/src/main/java/org/springframework/web/cors/CorsConfigurationSource.java b/spring-web/src/main/java/org/springframework/web/cors/CorsConfigurationSource.java
index 2fc6d9ce..48166caa 100644
--- a/spring-web/src/main/java/org/springframework/web/cors/CorsConfigurationSource.java
+++ b/spring-web/src/main/java/org/springframework/web/cors/CorsConfigurationSource.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2015 the original author or authors.
+ * Copyright 2002-2016 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.
@@ -29,6 +29,7 @@ public interface CorsConfigurationSource {
/**
* Return a {@link CorsConfiguration} based on the incoming request.
+ * @return the associated {@link CorsConfiguration}, or {@code null} if none
*/
CorsConfiguration getCorsConfiguration(HttpServletRequest request);
diff --git a/spring-web/src/main/java/org/springframework/web/filter/AbstractRequestLoggingFilter.java b/spring-web/src/main/java/org/springframework/web/filter/AbstractRequestLoggingFilter.java
index 607b8bc0..4062bf6d 100644
--- a/spring-web/src/main/java/org/springframework/web/filter/AbstractRequestLoggingFilter.java
+++ b/spring-web/src/main/java/org/springframework/web/filter/AbstractRequestLoggingFilter.java
@@ -46,7 +46,7 @@ import org.springframework.web.util.WebUtils;
*
* <p>Prefixes and suffixes for the before and after messages can be configured using the
* {@code beforeMessagePrefix}, {@code afterMessagePrefix}, {@code beforeMessageSuffix} and
- * {@code afterMessageSuffix} properties,
+ * {@code afterMessageSuffix} properties.
*
* @author Rob Harrop
* @author Juergen Hoeller
@@ -124,7 +124,6 @@ public abstract class AbstractRequestLoggingFilter extends OncePerRequestFilter
* <p>Should be configured using an {@code <init-param>} for parameter name
* "includePayload" in the filter definition in {@code web.xml}.
*/
-
public void setIncludePayload(boolean includePayload) {
this.includePayload = includePayload;
}
@@ -254,12 +253,14 @@ public abstract class AbstractRequestLoggingFilter extends OncePerRequestFilter
StringBuilder msg = new StringBuilder();
msg.append(prefix);
msg.append("uri=").append(request.getRequestURI());
+
if (isIncludeQueryString()) {
String queryString = request.getQueryString();
if (queryString != null) {
msg.append('?').append(queryString);
}
}
+
if (isIncludeClientInfo()) {
String client = request.getRemoteAddr();
if (StringUtils.hasLength(client)) {
@@ -274,6 +275,7 @@ public abstract class AbstractRequestLoggingFilter extends OncePerRequestFilter
msg.append(";user=").append(user);
}
}
+
if (isIncludePayload()) {
ContentCachingRequestWrapper wrapper =
WebUtils.getNativeRequest(request, ContentCachingRequestWrapper.class);
@@ -292,6 +294,7 @@ public abstract class AbstractRequestLoggingFilter extends OncePerRequestFilter
}
}
}
+
msg.append(suffix);
return msg.toString();
}
diff --git a/spring-web/src/main/java/org/springframework/web/filter/CorsFilter.java b/spring-web/src/main/java/org/springframework/web/filter/CorsFilter.java
index 8079532e..812deb0a 100644
--- a/spring-web/src/main/java/org/springframework/web/filter/CorsFilter.java
+++ b/spring-web/src/main/java/org/springframework/web/filter/CorsFilter.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2015 the original author or authors.
+ * Copyright 2002-2016 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.
@@ -31,10 +31,10 @@ import org.springframework.web.cors.DefaultCorsProcessor;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
/**
- * {@link javax.servlet.Filter} that handles CORS preflight requests and intercepts CORS
- * simple and actual requests thanks to a {@link CorsProcessor} implementation
- * ({@link DefaultCorsProcessor} by default) in order to add the relevant CORS response
- * headers (like {@code Access-Control-Allow-Origin}) using the provided
+ * {@link javax.servlet.Filter} that handles CORS preflight requests and intercepts
+ * CORS simple and actual requests thanks to a {@link CorsProcessor} implementation
+ * ({@link DefaultCorsProcessor} by default) in order to add the relevant CORS
+ * response headers (like {@code Access-Control-Allow-Origin}) using the provided
* {@link CorsConfigurationSource} (for example an {@link UrlBasedCorsConfigurationSource}
* instance.
*
@@ -52,20 +52,22 @@ import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
*/
public class CorsFilter extends OncePerRequestFilter {
- private CorsProcessor processor = new DefaultCorsProcessor();
-
private final CorsConfigurationSource configSource;
+ private CorsProcessor processor = new DefaultCorsProcessor();
+
/**
- * Constructor accepting a {@link CorsConfigurationSource} used by the filter to find
- * the {@link CorsConfiguration} to use for each incoming request.
+ * Constructor accepting a {@link CorsConfigurationSource} used by the filter
+ * to find the {@link CorsConfiguration} to use for each incoming request.
* @see UrlBasedCorsConfigurationSource
*/
public CorsFilter(CorsConfigurationSource configSource) {
+ Assert.notNull(configSource, "CorsConfigurationSource must not be null");
this.configSource = configSource;
}
+
/**
* Configure a custom {@link CorsProcessor} to use to apply the matched
* {@link CorsConfiguration} for a request.
@@ -76,6 +78,7 @@ public class CorsFilter extends OncePerRequestFilter {
this.processor = processor;
}
+
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
FilterChain filterChain) throws ServletException, IOException {
@@ -89,6 +92,7 @@ public class CorsFilter extends OncePerRequestFilter {
}
}
}
+
filterChain.doFilter(request, response);
}
diff --git a/spring-web/src/main/java/org/springframework/web/method/annotation/RequestParamMethodArgumentResolver.java b/spring-web/src/main/java/org/springframework/web/method/annotation/RequestParamMethodArgumentResolver.java
index aba8999a..c481b152 100644
--- a/spring-web/src/main/java/org/springframework/web/method/annotation/RequestParamMethodArgumentResolver.java
+++ b/spring-web/src/main/java/org/springframework/web/method/annotation/RequestParamMethodArgumentResolver.java
@@ -54,8 +54,8 @@ import org.springframework.web.util.WebUtils;
* abstraction, and arguments of type {@code javax.servlet.http.Part} in conjunction
* with Servlet 3.0 multipart requests. This resolver can also be created in default
* resolution mode in which simple types (int, long, etc.) not annotated with
- * @{@link RequestParam} are also treated as request parameters with the
- * parameter name derived from the argument name.
+ * {@link RequestParam @RequestParam} are also treated as request parameters with
+ * the parameter name derived from the argument name.
*
* <p>If the method parameter type is {@link Map}, the name specified in the
* annotation is used to resolve the request parameter String value. The value is
diff --git a/spring-web/src/main/java/org/springframework/web/util/UriComponentsBuilder.java b/spring-web/src/main/java/org/springframework/web/util/UriComponentsBuilder.java
index 31c0162e..74d0105e 100644
--- a/spring-web/src/main/java/org/springframework/web/util/UriComponentsBuilder.java
+++ b/spring-web/src/main/java/org/springframework/web/util/UriComponentsBuilder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2015 the original author or authors.
+ * Copyright 2002-2016 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.
@@ -24,6 +24,7 @@ import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpRequest;
import org.springframework.util.Assert;
import org.springframework.util.LinkedMultiValueMap;
@@ -130,7 +131,7 @@ public class UriComponentsBuilder implements Cloneable {
this.userInfo = other.userInfo;
this.host = other.host;
this.port = other.port;
- this.pathBuilder = (CompositePathComponentBuilder) other.pathBuilder.clone();
+ this.pathBuilder = other.pathBuilder.cloneBuilder();
this.queryParams.putAll(other.queryParams);
this.fragment = other.fragment;
}
@@ -271,72 +272,17 @@ public class UriComponentsBuilder implements Cloneable {
/**
* Create a new {@code UriComponents} object from the URI associated with
* the given HttpRequest while also overlaying with values from the headers
- * "Forwarded" (<a href="http://tools.ietf.org/html/rfc7239">RFC 7239</a>, or
- * "X-Forwarded-Host", "X-Forwarded-Port", and "X-Forwarded-Proto" if "Forwarded" is
- * not found.
+ * "Forwarded" (<a href="http://tools.ietf.org/html/rfc7239">RFC 7239</a>,
+ * or "X-Forwarded-Host", "X-Forwarded-Port", and "X-Forwarded-Proto" if
+ * "Forwarded" is not found.
* @param request the source request
* @return the URI components of the URI
* @since 4.1.5
*/
public static UriComponentsBuilder fromHttpRequest(HttpRequest request) {
- URI uri = request.getURI();
- UriComponentsBuilder builder = UriComponentsBuilder.fromUri(uri);
-
- String scheme = uri.getScheme();
- String host = uri.getHost();
- int port = uri.getPort();
-
- String forwardedHeader = request.getHeaders().getFirst("Forwarded");
- if (StringUtils.hasText(forwardedHeader)) {
- String forwardedToUse = StringUtils.commaDelimitedListToStringArray(forwardedHeader)[0];
- Matcher m = FORWARDED_HOST_PATTERN.matcher(forwardedToUse);
- if (m.find()) {
- host = m.group(1).trim();
- }
- m = FORWARDED_PROTO_PATTERN.matcher(forwardedToUse);
- if (m.find()) {
- scheme = m.group(1).trim();
- }
- }
- else {
- String hostHeader = request.getHeaders().getFirst("X-Forwarded-Host");
- if (StringUtils.hasText(hostHeader)) {
- String[] hosts = StringUtils.commaDelimitedListToStringArray(hostHeader);
- String hostToUse = hosts[0];
- if (hostToUse.contains(":")) {
- String[] hostAndPort = StringUtils.split(hostToUse, ":");
- host = hostAndPort[0];
- port = Integer.parseInt(hostAndPort[1]);
- }
- else {
- host = hostToUse;
- port = -1;
- }
- }
-
- String portHeader = request.getHeaders().getFirst("X-Forwarded-Port");
- if (StringUtils.hasText(portHeader)) {
- String[] ports = StringUtils.commaDelimitedListToStringArray(portHeader);
- port = Integer.parseInt(ports[0]);
- }
-
- String protocolHeader = request.getHeaders().getFirst("X-Forwarded-Proto");
- if (StringUtils.hasText(protocolHeader)) {
- String[] protocols = StringUtils.commaDelimitedListToStringArray(protocolHeader);
- scheme = protocols[0];
- }
- }
-
- builder.scheme(scheme);
- builder.host(host);
- builder.port(null);
- if (scheme.equals("http") && port != 80 || scheme.equals("https") && port != 443) {
- builder.port(port);
- }
- return builder;
+ return fromUri(request.getURI()).adaptFromForwardedHeaders(request.getHeaders());
}
-
/**
* Create an instance by parsing the "Origin" header of an HTTP request.
* @see <a href="https://tools.ietf.org/html/rfc6454">RFC 6454</a>
@@ -463,18 +409,6 @@ public class UriComponentsBuilder implements Cloneable {
return this;
}
- private void resetHierarchicalComponents() {
- this.userInfo = null;
- this.host = null;
- this.port = null;
- this.pathBuilder = new CompositePathComponentBuilder();
- this.queryParams.clear();
- }
-
- private void resetSchemeSpecificPart() {
- this.ssp = null;
- }
-
/**
* Set the URI scheme. The given scheme may contain URI template variables,
* and may also be {@code null} to clear the scheme of this builder.
@@ -724,17 +658,103 @@ public class UriComponentsBuilder implements Cloneable {
return this;
}
+ /**
+ * Adapt this builder's scheme+host+port from the given headers, specifically
+ * "Forwarded" (<a href="http://tools.ietf.org/html/rfc7239">RFC 7239</a>,
+ * or "X-Forwarded-Host", "X-Forwarded-Port", and "X-Forwarded-Proto" if
+ * "Forwarded" is not found.
+ * @param headers the HTTP headers to consider
+ * @return this UriComponentsBuilder
+ * @since 4.2.7
+ */
+ UriComponentsBuilder adaptFromForwardedHeaders(HttpHeaders headers) {
+ String forwardedHeader = headers.getFirst("Forwarded");
+ if (StringUtils.hasText(forwardedHeader)) {
+ String forwardedToUse = StringUtils.commaDelimitedListToStringArray(forwardedHeader)[0];
+ Matcher matcher = FORWARDED_HOST_PATTERN.matcher(forwardedToUse);
+ if (matcher.find()) {
+ host(matcher.group(1).trim());
+ }
+ matcher = FORWARDED_PROTO_PATTERN.matcher(forwardedToUse);
+ if (matcher.find()) {
+ scheme(matcher.group(1).trim());
+ }
+ }
+ else {
+ String hostHeader = headers.getFirst("X-Forwarded-Host");
+ if (StringUtils.hasText(hostHeader)) {
+ String[] hosts = StringUtils.commaDelimitedListToStringArray(hostHeader);
+ String hostToUse = hosts[0];
+ if (hostToUse.contains(":")) {
+ String[] hostAndPort = StringUtils.split(hostToUse, ":");
+ host(hostAndPort[0]);
+ port(Integer.parseInt(hostAndPort[1]));
+ }
+ else {
+ host(hostToUse);
+ port(null);
+ }
+ }
+
+ String portHeader = headers.getFirst("X-Forwarded-Port");
+ if (StringUtils.hasText(portHeader)) {
+ String[] ports = StringUtils.commaDelimitedListToStringArray(portHeader);
+ port(Integer.parseInt(ports[0]));
+ }
+
+ String protocolHeader = headers.getFirst("X-Forwarded-Proto");
+ if (StringUtils.hasText(protocolHeader)) {
+ String[] protocols = StringUtils.commaDelimitedListToStringArray(protocolHeader);
+ scheme(protocols[0]);
+ }
+ }
+
+ if ((this.scheme.equals("http") && "80".equals(this.port)) ||
+ (this.scheme.equals("https") && "443".equals(this.port))) {
+ this.port = null;
+ }
+
+ return this;
+ }
+
+ private void resetHierarchicalComponents() {
+ this.userInfo = null;
+ this.host = null;
+ this.port = null;
+ this.pathBuilder = new CompositePathComponentBuilder();
+ this.queryParams.clear();
+ }
+
+ private void resetSchemeSpecificPart() {
+ this.ssp = null;
+ }
+
+
+ /**
+ * Public declaration of Object's {@code clone()} method.
+ * Delegates to {@link #cloneBuilder()}.
+ * @see Object#clone()
+ */
@Override
public Object clone() {
+ return cloneBuilder();
+ }
+
+ /**
+ * Clone this {@code UriComponentsBuilder}.
+ * @return the cloned {@code UriComponentsBuilder} object
+ * @since 4.2.7
+ */
+ public UriComponentsBuilder cloneBuilder() {
return new UriComponentsBuilder(this);
}
- private interface PathComponentBuilder extends Cloneable {
+ private interface PathComponentBuilder {
PathComponent build();
- Object clone();
+ PathComponentBuilder cloneBuilder();
}
@@ -810,10 +830,10 @@ public class UriComponentsBuilder implements Cloneable {
}
@Override
- public Object clone() {
+ public CompositePathComponentBuilder cloneBuilder() {
CompositePathComponentBuilder compositeBuilder = new CompositePathComponentBuilder();
for (PathComponentBuilder builder : this.builders) {
- compositeBuilder.builders.add((PathComponentBuilder) builder.clone());
+ compositeBuilder.builders.add(builder.cloneBuilder());
}
return compositeBuilder;
}
@@ -852,7 +872,7 @@ public class UriComponentsBuilder implements Cloneable {
}
@Override
- public Object clone() {
+ public FullPathComponentBuilder cloneBuilder() {
FullPathComponentBuilder builder = new FullPathComponentBuilder();
builder.append(this.path.toString());
return builder;
@@ -879,7 +899,7 @@ public class UriComponentsBuilder implements Cloneable {
}
@Override
- public Object clone() {
+ public PathSegmentComponentBuilder cloneBuilder() {
PathSegmentComponentBuilder builder = new PathSegmentComponentBuilder();
builder.pathSegments.addAll(this.pathSegments);
return builder;
diff --git a/spring-web/src/main/java/org/springframework/web/util/WebUtils.java b/spring-web/src/main/java/org/springframework/web/util/WebUtils.java
index 76c5dd04..6d8062fb 100644
--- a/spring-web/src/main/java/org/springframework/web/util/WebUtils.java
+++ b/spring-web/src/main/java/org/springframework/web/util/WebUtils.java
@@ -34,6 +34,7 @@ import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.springframework.http.HttpRequest;
+import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.LinkedMultiValueMap;
@@ -811,18 +812,31 @@ public abstract class WebUtils {
if (origin == null) {
return true;
}
- UriComponents actualUrl = UriComponentsBuilder.fromHttpRequest(request).build();
+ UriComponentsBuilder urlBuilder;
+ if (request instanceof ServletServerHttpRequest) {
+ // Build more efficiently if we can: we only need scheme, host, port for origin comparison
+ HttpServletRequest servletRequest = ((ServletServerHttpRequest) request).getServletRequest();
+ urlBuilder = new UriComponentsBuilder().
+ scheme(servletRequest.getScheme()).
+ host(servletRequest.getServerName()).
+ port(servletRequest.getServerPort()).
+ adaptFromForwardedHeaders(request.getHeaders());
+ }
+ else {
+ urlBuilder = UriComponentsBuilder.fromHttpRequest(request);
+ }
+ UriComponents actualUrl = urlBuilder.build();
UriComponents originUrl = UriComponentsBuilder.fromOriginHeader(origin).build();
return (actualUrl.getHost().equals(originUrl.getHost()) && getPort(actualUrl) == getPort(originUrl));
}
- private static int getPort(UriComponents component) {
- int port = component.getPort();
+ private static int getPort(UriComponents uri) {
+ int port = uri.getPort();
if (port == -1) {
- if ("http".equals(component.getScheme()) || "ws".equals(component.getScheme())) {
+ if ("http".equals(uri.getScheme()) || "ws".equals(uri.getScheme())) {
port = 80;
}
- else if ("https".equals(component.getScheme()) || "wss".equals(component.getScheme())) {
+ else if ("https".equals(uri.getScheme()) || "wss".equals(uri.getScheme())) {
port = 443;
}
}