提交 8c4bc365 编写于 作者: J Juergen Hoeller

Polishing

上级 6807bcb8
......@@ -27,6 +27,7 @@ import java.util.concurrent.Callable;
*
* @author Costin Leau
* @author Juergen Hoeller
* @author Stephane Nicoll
* @since 3.1
*/
public interface Cache {
......@@ -164,7 +165,7 @@ public interface Cache {
private final Object key;
public ValueRetrievalException(Object key, Callable<?> loader, Throwable ex) {
super(String.format("Value for key '%s' could not " + "be loaded using '%s'", key, loader), ex);
super(String.format("Value for key '%s' could not be loaded using '%s'", key, loader), ex);
this.key = key;
}
......
......@@ -1458,6 +1458,7 @@ public class AnnotatedElementUtils {
List<T> getAggregatedResults();
}
/**
* {@link Processor} that {@linkplain #process(AnnotatedElement, Annotation, int)
* processes} annotations but does not {@linkplain #postProcess post-process} or
......@@ -1468,7 +1469,6 @@ public class AnnotatedElementUtils {
private final boolean alwaysProcesses;
public SimpleAnnotationProcessor() {
this(false);
}
......@@ -1498,6 +1498,7 @@ public class AnnotatedElementUtils {
}
}
/**
* {@link SimpleAnnotationProcessor} that always returns {@link Boolean#TRUE} when
* asked to {@linkplain #process(AnnotatedElement, Annotation, int) process} an
......@@ -1512,6 +1513,7 @@ public class AnnotatedElementUtils {
}
}
/**
* {@link Processor} that gets the {@code AnnotationAttributes} for the
* target annotation during the {@link #process} phase and then merges
......@@ -1533,7 +1535,6 @@ public class AnnotatedElementUtils {
private final List<AnnotationAttributes> aggregatedResults;
MergedAnnotationAttributesProcessor() {
this(false, false, false);
}
......@@ -1635,7 +1636,6 @@ public class AnnotatedElementUtils {
Object value = AnnotationUtils.getValue(annotation, sourceAttributeName);
return AnnotationUtils.adaptValue(element, value, this.classValuesAsString, this.nestedAnnotationsAsMap);
}
}
}
......@@ -31,10 +31,12 @@ abstract class AbstractConditionalEnumConverter implements ConditionalConverter
private final ConversionService conversionService;
protected AbstractConditionalEnumConverter(ConversionService conversionService) {
this.conversionService = conversionService;
}
@Override
public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) {
for (Class<?> interfaceType : ClassUtils.getAllInterfacesForClass(sourceType.getType())) {
......
/*
* 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.
* 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.lang;
import java.lang.annotation.Documented;
......
......@@ -136,19 +136,16 @@ abstract class BootstrapUtils {
testContextBootstrapper.setBootstrapContext(bootstrapContext);
return testContextBootstrapper;
}
catch (IllegalStateException ex) {
throw ex;
}
catch (Throwable ex) {
if (ex instanceof IllegalStateException) {
throw (IllegalStateException) ex;
}
throw new IllegalStateException("Could not load TestContextBootstrapper [" + clazz +
"]. Specify @BootstrapWith's 'value' attribute or make the default bootstrapper class available.",
ex);
}
}
/**
* @since 4.3
*/
private static Class<?> resolveExplicitTestContextBootstrapper(Class<?> testClass) {
Set<BootstrapWith> annotations = AnnotatedElementUtils.findAllMergedAnnotations(testClass, BootstrapWith.class);
if (annotations.size() < 1) {
......@@ -162,9 +159,6 @@ abstract class BootstrapUtils {
return annotations.iterator().next().value();
}
/**
* @since 4.3
*/
private static Class<?> resolveDefaultTestContextBootstrapper(Class<?> testClass) throws Exception {
ClassLoader classLoader = BootstrapUtils.class.getClassLoader();
AnnotationAttributes attributes = AnnotatedElementUtils.findMergedAnnotationAttributes(testClass,
......
......@@ -42,12 +42,13 @@ import org.springframework.util.StringUtils;
*/
public class ContextConfigurationAttributes {
private static final Log logger = LogFactory.getLog(ContextConfigurationAttributes.class);
private static final String[] EMPTY_LOCATIONS = new String[0];
private static final Class<?>[] EMPTY_CLASSES = new Class<?>[0];
private static final Log logger = LogFactory.getLog(ContextConfigurationAttributes.class);
private final Class<?> declaringClass;
private Class<?>[] classes;
......@@ -66,8 +67,7 @@ public class ContextConfigurationAttributes {
/**
* Construct a new {@link ContextConfigurationAttributes} instance with default
* values.
* Construct a new {@link ContextConfigurationAttributes} instance with default values.
* @param declaringClass the test class that declared {@code @ContextConfiguration},
* either explicitly or implicitly
* @since 4.3
......@@ -101,8 +101,8 @@ public class ContextConfigurationAttributes {
@SuppressWarnings("unchecked")
public ContextConfigurationAttributes(Class<?> declaringClass, AnnotationAttributes annAttrs) {
this(declaringClass, annAttrs.getStringArray("locations"), annAttrs.getClassArray("classes"), annAttrs.getBoolean("inheritLocations"),
(Class<? extends ApplicationContextInitializer<? extends ConfigurableApplicationContext>>[]) annAttrs.getClassArray("initializers"),
annAttrs.getBoolean("inheritInitializers"), annAttrs.getString("name"), (Class<? extends ContextLoader>) annAttrs.getClass("loader"));
(Class<? extends ApplicationContextInitializer<? extends ConfigurableApplicationContext>>[]) annAttrs.getClassArray("initializers"),
annAttrs.getBoolean("inheritInitializers"), annAttrs.getString("name"), (Class<? extends ContextLoader>) annAttrs.getClass("loader"));
}
/**
......@@ -156,8 +156,8 @@ public class ContextConfigurationAttributes {
if (!ObjectUtils.isEmpty(locations) && !ObjectUtils.isEmpty(classes) && logger.isDebugEnabled()) {
logger.debug(String.format(
"Test class [%s] has been configured with @ContextConfiguration's 'locations' (or 'value') %s " +
"and 'classes' %s attributes. Most SmartContextLoader implementations support " +
"only one declaration of resources per @ContextConfiguration annotation.",
"and 'classes' %s attributes. Most SmartContextLoader implementations support " +
"only one declaration of resources per @ContextConfiguration annotation.",
declaringClass.getName(), ObjectUtils.nullSafeToString(locations),
ObjectUtils.nullSafeToString(classes)));
}
......
......@@ -27,11 +27,6 @@ import org.springframework.util.StringUtils;
*/
public abstract class ContextCacheUtils {
private ContextCacheUtils() {
/* no-op */
}
/**
* Retrieve the maximum size of the {@link ContextCache}.
* <p>Uses {@link SpringProperties} to retrieve a system property or Spring
......@@ -49,7 +44,7 @@ public abstract class ContextCacheUtils {
}
}
catch (Exception ex) {
/* ignore */
// ignore
}
// Fallback
......
......@@ -99,7 +99,7 @@ public class DefaultContextCache implements ContextCache {
* @see #DefaultContextCache()
*/
public DefaultContextCache(int maxSize) {
Assert.isTrue(maxSize > 0, "maxSize must be positive");
Assert.isTrue(maxSize > 0, "'maxSize' must be positive");
this.maxSize = maxSize;
}
......@@ -314,16 +314,14 @@ public class DefaultContextCache implements ContextCache {
* Simple cache implementation based on {@link LinkedHashMap} with a maximum
* size and a <em>least recently used</em> (LRU) eviction policy that
* properly closes application contexts.
*
* @author Sam Brannen
* @since 4.3
*/
@SuppressWarnings("serial")
private class LruCache extends LinkedHashMap<MergedContextConfiguration, ApplicationContext> {
/**
* Create a new {@code LruCache} with the supplied initial capacity and
* load factor.
* Create a new {@code LruCache} with the supplied initial capacity
* and load factor.
* @param initialCapacity the initial capacity
* @param loadFactor the load factor
*/
......
......@@ -308,23 +308,20 @@ public abstract class AbstractTestContextBootstrapper implements TestContextBoot
}
}
/**
* @since 4.3
*/
private MergedContextConfiguration buildDefaultMergedContextConfiguration(Class<?> testClass,
CacheAwareContextLoaderDelegate cacheAwareContextLoaderDelegate) {
List<ContextConfigurationAttributes> defaultConfigAttributesList
= Collections.singletonList(new ContextConfigurationAttributes(testClass));
List<ContextConfigurationAttributes> defaultConfigAttributesList =
Collections.singletonList(new ContextConfigurationAttributes(testClass));
ContextLoader contextLoader = resolveContextLoader(testClass, defaultConfigAttributesList);
if (logger.isInfoEnabled()) {
logger.info(String.format(
"Neither @ContextConfiguration nor @ContextHierarchy found for test class [%s], using %s",
testClass.getName(), contextLoader.getClass().getSimpleName()));
"Neither @ContextConfiguration nor @ContextHierarchy found for test class [%s], using %s",
testClass.getName(), contextLoader.getClass().getSimpleName()));
}
return buildMergedContextConfiguration(testClass, defaultConfigAttributesList, null,
cacheAwareContextLoaderDelegate, false);
cacheAwareContextLoaderDelegate, false);
}
/**
......@@ -367,7 +364,7 @@ public abstract class AbstractTestContextBootstrapper implements TestContextBoot
for (ContextConfigurationAttributes configAttributes : configAttributesList) {
if (logger.isTraceEnabled()) {
logger.trace(String.format("Processing locations and classes for context configuration attributes %s",
configAttributes));
configAttributes));
}
if (contextLoader instanceof SmartContextLoader) {
SmartContextLoader smartContextLoader = (SmartContextLoader) contextLoader;
......@@ -412,9 +409,6 @@ public abstract class AbstractTestContextBootstrapper implements TestContextBoot
return processMergedContextConfiguration(mergedConfig);
}
/**
* @since 4.3
*/
private Set<ContextCustomizer> getContextCustomizers(Class<?> testClass,
List<ContextConfigurationAttributes> configAttributes) {
......@@ -441,18 +435,6 @@ public abstract class AbstractTestContextBootstrapper implements TestContextBoot
return SpringFactoriesLoader.loadFactories(ContextCustomizerFactory.class, getClass().getClassLoader());
}
/**
* @since 4.3
*/
private boolean areAllEmpty(Collection<?>... collections) {
for (Collection<?> collection : collections) {
if (!collection.isEmpty()) {
return false;
}
}
return true;
}
/**
* Resolve the {@link ContextLoader} {@linkplain Class class} to use for the
* supplied list of {@link ContextConfigurationAttributes} and then instantiate
......@@ -575,4 +557,14 @@ public abstract class AbstractTestContextBootstrapper implements TestContextBoot
return mergedConfig;
}
private static boolean areAllEmpty(Collection<?>... collections) {
for (Collection<?> collection : collections) {
if (!collection.isEmpty()) {
return false;
}
}
return true;
}
}
......@@ -39,7 +39,7 @@ import org.springframework.core.io.ResourceLoader;
import org.springframework.core.io.support.ResourcePropertySource;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.util.TestContextResourceUtils;
import org.springframework.test.util.MetaAnnotationUtils.AnnotationDescriptor;
import org.springframework.test.util.MetaAnnotationUtils.*;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
......@@ -58,8 +58,6 @@ import static org.springframework.test.util.MetaAnnotationUtils.*;
*/
public abstract class TestPropertySourceUtils {
private static final Log logger = LogFactory.getLog(TestPropertySourceUtils.class);
/**
* The name of the {@link MapPropertySource} created from <em>inlined properties</em>.
* @since 4.1.5
......@@ -67,10 +65,8 @@ public abstract class TestPropertySourceUtils {
*/
public static final String INLINED_PROPERTIES_PROPERTY_SOURCE_NAME = "Inlined Test Properties";
private static final Log logger = LogFactory.getLog(TestPropertySourceUtils.class);
private TestPropertySourceUtils() {
/* no-op */
}
static MergedTestPropertySources buildMergedTestPropertySources(Class<?> testClass) {
Class<TestPropertySource> annotationType = TestPropertySource.class;
......
......@@ -106,6 +106,7 @@ public class ServletTestExecutionListener extends AbstractTestExecutionListener
public static final String ACTIVATE_LISTENER = Conventions.getQualifiedAttributeName(
ServletTestExecutionListener.class, "activateListener");
private static final Log logger = LogFactory.getLog(ServletTestExecutionListener.class);
......@@ -122,7 +123,6 @@ public class ServletTestExecutionListener extends AbstractTestExecutionListener
* callback phase via Spring Web's {@link RequestContextHolder}, but only if
* the {@linkplain TestContext#getTestClass() test class} is annotated with
* {@link WebAppConfiguration @WebAppConfiguration}.
*
* @see TestExecutionListener#prepareTestInstance(TestContext)
* @see #setUpRequestContextIfNecessary(TestContext)
*/
......@@ -136,7 +136,6 @@ public class ServletTestExecutionListener extends AbstractTestExecutionListener
* {@link RequestContextHolder}, but only if the
* {@linkplain TestContext#getTestClass() test class} is annotated with
* {@link WebAppConfiguration @WebAppConfiguration}.
*
* @see TestExecutionListener#beforeTestMethod(TestContext)
* @see #setUpRequestContextIfNecessary(TestContext)
*/
......@@ -154,11 +153,9 @@ public class ServletTestExecutionListener extends AbstractTestExecutionListener
* into the test instance for subsequent tests by setting the
* {@link DependencyInjectionTestExecutionListener#REINJECT_DEPENDENCIES_ATTRIBUTE}
* in the test context to {@code true}.
*
* <p>The {@link #RESET_REQUEST_CONTEXT_HOLDER_ATTRIBUTE} and
* {@link #POPULATED_REQUEST_CONTEXT_HOLDER_ATTRIBUTE} will be subsequently
* removed from the test context, regardless of their values.
*
* @see TestExecutionListener#afterTestMethod(TestContext)
*/
@Override
......
......@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.test.web.client;
import java.io.IOException;
......@@ -33,7 +34,7 @@ import org.springframework.util.Assert;
* for storing expectations and actual requests, and checking for unsatisfied
* expectations at the end.
*
* <p>Sub-classes are responsible for validating each request by matching it to
* <p>Subclasses are responsible for validating each request by matching it to
* to expectations following the order of declaration or not.
*
* @author Rossen Stoyanchev
......@@ -57,7 +58,7 @@ public abstract class AbstractRequestExpectationManager implements RequestExpect
@Override
public ResponseActions expectRequest(ExpectedCount count, RequestMatcher matcher) {
Assert.state(getRequests().isEmpty(), "Cannot add more expectations after actual requests are made.");
Assert.state(getRequests().isEmpty(), "Cannot add more expectations after actual requests are made");
RequestExpectation expectation = new DefaultRequestExpectation(count, matcher);
getExpectations().add(expectation);
return expectation;
......@@ -81,11 +82,10 @@ public abstract class AbstractRequestExpectationManager implements RequestExpect
}
/**
* Sub-classes must implement the actual validation of the request
* Subclasses must implement the actual validation of the request
* matching it to a declared expectation.
*/
protected abstract ClientHttpResponse validateRequestInternal(ClientHttpRequest request)
throws IOException;
protected abstract ClientHttpResponse validateRequestInternal(ClientHttpRequest request) throws IOException;
@Override
public void verify() {
......@@ -149,7 +149,6 @@ public abstract class AbstractRequestExpectationManager implements RequestExpect
private final Set<RequestExpectation> expectations = new LinkedHashSet<RequestExpectation>();
public Set<RequestExpectation> getExpectations() {
return this.expectations;
}
......
......@@ -87,11 +87,12 @@ public class DefaultRequestExpectation implements RequestExpectation {
@Override
public ClientHttpResponse createResponse(ClientHttpRequest request) throws IOException {
if (getResponseCreator() == null) {
throw new IllegalStateException("createResponse called before ResponseCreator was set.");
ResponseCreator responseCreator = getResponseCreator();
if (responseCreator == null) {
throw new IllegalStateException("createResponse called before ResponseCreator was set");
}
getRequestCount().incrementAndValidate();
return getResponseCreator().createResponse(request);
return responseCreator.createResponse(request);
}
@Override
......@@ -114,12 +115,10 @@ public class DefaultRequestExpectation implements RequestExpectation {
private int matchedRequestCount;
public RequestCount(ExpectedCount expectedCount) {
this.expectedCount = expectedCount;
}
public ExpectedCount getExpectedCount() {
return this.expectedCount;
}
......
......@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.test.web.client;
import org.springframework.util.Assert;
......
......@@ -83,11 +83,9 @@ public class MockRestServiceServer {
* Set up an expectation for a single HTTP request. The returned
* {@link ResponseActions} can be used to set up further expectations as
* well as to define the response.
*
* <p>This method may be invoked any number times before starting to make
* request through the underlying {@code RestTemplate} in order to set up
* all expected requests.
*
* @param matcher request matcher
* @return a representation of the expectation
*/
......@@ -98,11 +96,9 @@ public class MockRestServiceServer {
/**
* An alternative to {@link #expect(RequestMatcher)} with an indication how
* many times the request is expected to be executed.
*
* <p>When request expectations have an expected count greater than one, only
* the first execution is expected to match the order of declaration. Subsequent
* request executions may be inserted anywhere thereafter.
*
* @param count the expected count
* @param matcher request matcher
* @return a representation of the expectation
......@@ -194,10 +190,8 @@ public class MockRestServiceServer {
/**
* Whether to allow expected requests to be executed in any order not
* necessarily matching the order of declaration.
*
* <p>When set to "true" this is effectively a shortcut for:<br>
* {@code builder.build(new UnorderedRequestExpectationManager)}.
*
* @param ignoreExpectOrder whether to ignore the order of expectations
*/
MockRestServiceServerBuilder ignoreExpectOrder(boolean ignoreExpectOrder);
......@@ -214,9 +208,9 @@ public class MockRestServiceServer {
* {@link RequestExpectationManager}.
*/
MockRestServiceServer build(RequestExpectationManager manager);
}
private static class DefaultBuilder implements MockRestServiceServerBuilder {
private final RestTemplate restTemplate;
......@@ -225,20 +219,18 @@ public class MockRestServiceServer {
private boolean ignoreExpectOrder;
public DefaultBuilder(RestTemplate restTemplate) {
Assert.notNull(restTemplate, "'restTemplate' must not be null");
Assert.notNull(restTemplate, "RestTemplate must not be null");
this.restTemplate = restTemplate;
this.asyncRestTemplate = null;
}
public DefaultBuilder(AsyncRestTemplate asyncRestTemplate) {
Assert.notNull(asyncRestTemplate, "'asyncRestTemplate' must not be null");
Assert.notNull(asyncRestTemplate, "AsyncRestTemplate must not be null");
this.restTemplate = null;
this.asyncRestTemplate = asyncRestTemplate;
}
@Override
public MockRestServiceServerBuilder ignoreExpectOrder(boolean ignoreExpectOrder) {
this.ignoreExpectOrder = ignoreExpectOrder;
......
......@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.test.web.client;
/**
......
......@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.test.web.client;
import java.io.IOException;
......
......@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.test.web.client;
import java.io.IOException;
......@@ -26,9 +27,9 @@ import org.springframework.util.Assert;
* Simple {@code RequestExpectationManager} that matches requests to expectations
* sequentially, i.e. in the order of declaration of expectations.
*
* <p>When request expectations have an expected count greater than one, only
* the first execution is expected to match the order of declaration. Subsequent
* request executions may be inserted anywhere thereafter.
* <p>When request expectations have an expected count greater than one,
* only the first execution is expected to match the order of declaration.
* Subsequent request executions may be inserted anywhere thereafter.
*
* @author Rossen Stoyanchev
* @since 4.3
......@@ -77,4 +78,5 @@ public class SimpleRequestExpectationManager extends AbstractRequestExpectationM
this.expectationIterator = null;
this.repeatExpectations.reset();
}
}
......@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.test.web.client;
import java.io.IOException;
......@@ -22,7 +23,7 @@ import org.springframework.http.client.ClientHttpResponse;
/**
* {@code RequestExpectationManager} that matches requests to expectations
* regardless of the order of declaration of expectated requests.
* regardless of the order of declaration of expected requests.
*
* @author Rossen Stoyanchev
* @since 4.3
......
......@@ -159,8 +159,8 @@ public abstract class MockMvcWebConnectionBuilderSupport<T extends MockMvcWebCon
* Create a new {@link WebConnection} that will use a {@link MockMvc}
* instance if one of the specified {@link WebRequestMatcher} instances
* matches.
* @param webClient the WebClient to use if none of
* the specified {@code WebRequestMatcher} instances matches; never {@code null}
* @param webClient the WebClient to use if none of the specified
* {@code WebRequestMatcher} instances matches (never {@code null})
* @return a new {@code WebConnection} that will use a {@code MockMvc}
* instance if one of the specified {@code WebRequestMatcher} matches
* @see #alwaysUseMockMvc()
......
......@@ -149,8 +149,8 @@ public class MockHttpServletRequestBuilder
* @since 4.3
*/
MockHttpServletRequestBuilder(String httpMethod, URI url) {
Assert.notNull(httpMethod, "httpMethod is required");
Assert.notNull(url, "url is required");
Assert.notNull(httpMethod, "'httpMethod' is required");
Assert.notNull(url, "'url' is required");
this.method = httpMethod;
this.url = url;
}
......
/*
* 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.
......@@ -45,20 +45,6 @@ public abstract class HttpRange {
private static final String BYTE_RANGE_PREFIX = "bytes=";
/**
* Return the start of the range given the total length of a representation.
* @param length the length of the representation
* @return the start of this range for the representation
*/
public abstract long getRangeStart(long length);
/**
* Return the end of the range (inclusive) given the total length of a representation.
* @param length the length of the representation
* @return the end of the range for the representation
*/
public abstract long getRangeEnd(long length);
/**
* Turn a {@code Resource} into a {@link ResourceRegion} using the range
* information contained in the current {@code HttpRange}.
......@@ -78,11 +64,25 @@ public abstract class HttpRange {
long end = getRangeEnd(contentLength);
return new ResourceRegion(resource, start, end - start + 1);
}
catch (IOException exc) {
throw new IllegalArgumentException("Can't convert this Resource to a ResourceRegion", exc);
catch (IOException ex) {
throw new IllegalArgumentException("Failed to convert Resource to ResourceRegion", ex);
}
}
/**
* Return the start of the range given the total length of a representation.
* @param length the length of the representation
* @return the start of this range for the representation
*/
public abstract long getRangeStart(long length);
/**
* Return the end of the range (inclusive) given the total length of a representation.
* @param length the length of the representation
* @return the end of the range for the representation
*/
public abstract long getRangeEnd(long length);
/**
* Create an {@code HttpRange} from the given position to the end.
......@@ -165,7 +165,6 @@ public abstract class HttpRange {
* Convert each {@code HttpRange} into a {@code ResourceRegion},
* selecting the appropriate segment of the given {@code Resource}
* using the HTTP Range information.
*
* @param ranges the list of ranges
* @param resource the resource to select the regions from
* @return the list of regions for the given resource
......
......@@ -156,13 +156,20 @@ public class RequestEntity<T> extends HttpEntity<T> {
/**
* Return the type of the request's body.
* @return the request's body type
* @return the request's body type, or {@code null} if not known
* @since 4.3
*/
public Type getType() {
return (this.type == null && this.getBody() != null ? this.getBody().getClass() : this.type );
if (this.type == null) {
T body = getBody();
if (body != null) {
return body.getClass();
}
}
return this.type;
}
@Override
public boolean equals(Object other) {
if (this == other) {
......@@ -172,8 +179,8 @@ public class RequestEntity<T> extends HttpEntity<T> {
return false;
}
RequestEntity<?> otherEntity = (RequestEntity<?>) other;
return (ObjectUtils.nullSafeEquals(this.method, otherEntity.method) &&
ObjectUtils.nullSafeEquals(this.url, otherEntity.url));
return (ObjectUtils.nullSafeEquals(getMethod(), otherEntity.getMethod()) &&
ObjectUtils.nullSafeEquals(getUrl(), otherEntity.getUrl()));
}
@Override
......@@ -187,9 +194,9 @@ public class RequestEntity<T> extends HttpEntity<T> {
@Override
public String toString() {
StringBuilder builder = new StringBuilder("<");
builder.append(this.method);
builder.append(getMethod());
builder.append(' ');
builder.append(this.url);
builder.append(getUrl());
builder.append(',');
T body = getBody();
HttpHeaders headers = getHeaders();
......
/*
* 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.
......@@ -16,16 +16,16 @@
package org.springframework.http.client;
import java.io.IOException;
import org.springframework.http.HttpRequest;
import org.springframework.util.concurrent.ListenableFuture;
import java.io.IOException;
/**
* Represents the context of a client-side HTTP request execution.
*
* <p>Used to invoke the next interceptor in the interceptor chain, or - if the
* calling interceptor is last - execute the request itself.
* <p>Used to invoke the next interceptor in the interceptor chain, or -
* if the calling interceptor is last - execute the request itself.
*
* @author Jakub Narloch
* @author Rossen Stoyanchev
......@@ -35,15 +35,13 @@ import java.io.IOException;
public interface AsyncClientHttpRequestExecution {
/**
* Resume the request execution by invoking next interceptor in the chain
* Resume the request execution by invoking the next interceptor in the chain
* or executing the request to the remote service.
*
* @param request the http request, containing the http method and headers
* @param body the body of the request
* @return the future
* @param request the HTTP request, containing the HTTP method and headers
* @param body the body of the request
* @return a corresponding future handle
* @throws IOException in case of I/O errors
*/
ListenableFuture<ClientHttpResponse> executeAsync(HttpRequest request, byte[] body)
throws IOException;
ListenableFuture<ClientHttpResponse> executeAsync(HttpRequest request, byte[] body) throws IOException;
}
\ No newline at end of file
}
/*
* 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.
......@@ -16,20 +16,19 @@
package org.springframework.http.client;
import java.io.IOException;
import org.springframework.http.HttpRequest;
import org.springframework.http.client.support.InterceptingAsyncHttpAccessor;
import org.springframework.util.concurrent.ListenableFuture;
import java.io.IOException;
/**
* Intercepts client-side HTTP requests. Implementations of this interface can be
* {@linkplain org.springframework.web.client.AsyncRestTemplate#setInterceptors(java.util.List)
* registered} with the {@link org.springframework.web.client.AsyncRestTemplate
* AsyncRestTemplate} as to modify the outgoing {@link HttpRequest} and/or
* register to modify the incoming {@link ClientHttpResponse} with help of a
* {@link org.springframework.util.concurrent.ListenableFutureAdapter
* ListenableFutureAdapter}.
* {@linkplain org.springframework.web.client.AsyncRestTemplate#setInterceptors registered}
* with the {@link org.springframework.web.client.AsyncRestTemplate} as to modify
* the outgoing {@link HttpRequest} and/or register to modify the incoming
* {@link ClientHttpResponse} with help of a
* {@link org.springframework.util.concurrent.ListenableFutureAdapter}.
*
* <p>The main entry point for interceptors is {@link #intercept}.
*
......@@ -41,34 +40,32 @@ import java.io.IOException;
*/
public interface AsyncClientHttpRequestInterceptor {
/**
* Intercept the given request, and return a response future. The given
* {@link AsyncClientHttpRequestExecution} allows the interceptor to pass on
* the request to the next entity in the chain.
*
* <p>An implementation might follow this pattern:
* <ol>
* <li>Examine the {@linkplain HttpRequest request} and body</li>
* <li>Optionally {@linkplain org.springframework.http.client.support.HttpRequestWrapper
* wrap} the request to filter HTTP attributes.</li>
* <li>Optionally modify the body of the request.</li>
* <li>One of the following:
* <ul>
* <li>execute the request through {@link ClientHttpRequestExecution}</li>
* <li>don't execute the request to block the execution altogether</li>
* </ul>
* <li>Optionally adapt the response to filter HTTP attributes with the help of
* {@link org.springframework.util.concurrent.ListenableFutureAdapter
* ListenableFutureAdapter}.</li>
* </ol>
*
* @param request the request, containing method, URI, and headers
* @param body the body of the request
* @param execution the request execution
* @return the response future
* @throws IOException in case of I/O errors
*/
ListenableFuture<ClientHttpResponse> intercept(HttpRequest request, byte[] body,
AsyncClientHttpRequestExecution execution) throws IOException;
/**
* Intercept the given request, and return a response future. The given
* {@link AsyncClientHttpRequestExecution} allows the interceptor to pass on
* the request to the next entity in the chain.
* <p>An implementation might follow this pattern:
* <ol>
* <li>Examine the {@linkplain HttpRequest request} and body</li>
* <li>Optionally {@linkplain org.springframework.http.client.support.HttpRequestWrapper
* wrap} the request to filter HTTP attributes.</li>
* <li>Optionally modify the body of the request.</li>
* <li>One of the following:
* <ul>
* <li>execute the request through {@link ClientHttpRequestExecution}</li>
* <li>don't execute the request to block the execution altogether</li>
* </ul>
* <li>Optionally adapt the response to filter HTTP attributes with the help of
* {@link org.springframework.util.concurrent.ListenableFutureAdapter
* ListenableFutureAdapter}.</li>
* </ol>
* @param request the request, containing method, URI, and headers
* @param body the body of the request
* @param execution the request execution
* @return the response future
* @throws IOException in case of I/O errors
*/
ListenableFuture<ClientHttpResponse> intercept(HttpRequest request, byte[] body,
AsyncClientHttpRequestExecution execution) throws IOException;
}
/*
* 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.
......@@ -32,29 +32,28 @@ import org.springframework.http.HttpMethod;
*/
public class InterceptingAsyncClientHttpRequestFactory implements AsyncClientHttpRequestFactory {
private AsyncClientHttpRequestFactory delegate;
private AsyncClientHttpRequestFactory delegate;
private List<AsyncClientHttpRequestInterceptor> interceptors;
private List<AsyncClientHttpRequestInterceptor> interceptors;
/**
* Create new instance of {@link InterceptingAsyncClientHttpRequestFactory}
* with delegated request factory and list of interceptors.
*
* @param delegate the request factory to delegate to
* @param interceptors the list of interceptors to use
*/
public InterceptingAsyncClientHttpRequestFactory(AsyncClientHttpRequestFactory delegate,
List<AsyncClientHttpRequestInterceptor> interceptors) {
/**
* Create new instance of {@link InterceptingAsyncClientHttpRequestFactory}
* with delegated request factory and list of interceptors.
* @param delegate the request factory to delegate to
* @param interceptors the list of interceptors to use
*/
public InterceptingAsyncClientHttpRequestFactory(AsyncClientHttpRequestFactory delegate,
List<AsyncClientHttpRequestInterceptor> interceptors) {
this.delegate = delegate;
this.interceptors = (interceptors != null ? interceptors :
Collections.<AsyncClientHttpRequestInterceptor>emptyList());
}
this.delegate = delegate;
this.interceptors = (interceptors != null ? interceptors : Collections.<AsyncClientHttpRequestInterceptor>emptyList());
}
@Override
public AsyncClientHttpRequest createAsyncRequest(URI uri, HttpMethod method) {
return new InterceptingAsyncClientHttpRequest(this.delegate, this.interceptors, uri, method);
}
@Override
public AsyncClientHttpRequest createAsyncRequest(URI uri, HttpMethod method) {
return new InterceptingAsyncClientHttpRequest(this.delegate, this.interceptors, uri, method);
}
}
/*
* 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.
......@@ -16,17 +16,17 @@
package org.springframework.http.client.support;
import java.util.ArrayList;
import java.util.List;
import org.springframework.http.client.AsyncClientHttpRequestFactory;
import org.springframework.http.client.AsyncClientHttpRequestInterceptor;
import org.springframework.http.client.InterceptingAsyncClientHttpRequestFactory;
import org.springframework.util.CollectionUtils;
import java.util.ArrayList;
import java.util.List;
/**
* The HTTP accessor that extends the base {@link AsyncHttpAccessor} with request
* intercepting functionality.
* The HTTP accessor that extends the base {@link AsyncHttpAccessor} with
* request intercepting functionality.
*
* @author Jakub Narloch
* @author Rossen Stoyanchev
......@@ -39,8 +39,7 @@ public abstract class InterceptingAsyncHttpAccessor extends AsyncHttpAccessor {
/**
* Sets the request interceptors that this accessor should use.
*
* Set the request interceptors that this accessor should use.
* @param interceptors the list of interceptors
*/
public void setInterceptors(List<AsyncClientHttpRequestInterceptor> interceptors) {
......@@ -54,6 +53,7 @@ public abstract class InterceptingAsyncHttpAccessor extends AsyncHttpAccessor {
return this.interceptors;
}
@Override
public AsyncClientHttpRequestFactory getAsyncRequestFactory() {
AsyncClientHttpRequestFactory delegate = super.getAsyncRequestFactory();
......
......@@ -65,7 +65,7 @@ public class ResourceRegionHttpMessageConverter extends AbstractGenericHttpMessa
}
@Override
protected ResourceRegion readInternal(Class<? extends Object> clazz, HttpInputMessage inputMessage)
protected ResourceRegion readInternal(Class<?> clazz, HttpInputMessage inputMessage)
throws IOException, HttpMessageNotReadableException {
return null;
......@@ -119,10 +119,8 @@ public class ResourceRegionHttpMessageConverter extends AbstractGenericHttpMessa
}
}
protected void writeResourceRegion(ResourceRegion region, HttpOutputMessage outputMessage)
throws IOException {
Assert.notNull(region, "ResourceRegion should not be null");
protected void writeResourceRegion(ResourceRegion region, HttpOutputMessage outputMessage) throws IOException {
Assert.notNull(region, "ResourceRegion must not be null");
HttpHeaders responseHeaders = outputMessage.getHeaders();
long start = region.getPosition();
long end = start + region.getCount() - 1;
......@@ -179,6 +177,7 @@ public class ResourceRegionHttpMessageConverter extends AbstractGenericHttpMessa
}
private static void println(OutputStream os) throws IOException {
os.write('\r');
os.write('\n');
......
......@@ -77,12 +77,11 @@ public @interface ModelAttribute {
String name() default "";
/**
* Allows declaring data binding disabled directly on an
* {@code @ModelAttribute} method parameter or on the attribute returned from
* an {@code @ModelAttribute} method, both of which would prevent data
* binding for that attribute.
* <p>By default this is set to "true" in which case data binding applies.
* Set this to "false" to disable data binding.
* Allows declaring data binding disabled directly on an {@code @ModelAttribute}
* method parameter or on the attribute returned from an {@code @ModelAttribute}
* method, both of which would prevent data binding for that attribute.
* <p>By default this is set to {@code true} in which case data binding applies.
* Set this to {@code false} to disable data binding.
* @since 4.3
*/
boolean binding() default true;
......
/*
* 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,9 +56,9 @@ public @interface RequestAttribute {
/**
* Whether the request attribute is required.
* <p>Defaults to {@code true}, leading to an exception being thrown
* if the attribute is missing. Switch this to {@code false} if you prefer
* a {@code null} or Java 1.8+ {@code java.util.Optional} if the attribute
* <p>Defaults to {@code true}, leading to an exception being thrown if
* the attribute is missing. Switch this to {@code false} if you prefer
* a {@code null} or Java 8 {@code java.util.Optional} if the attribute
* doesn't exist.
*/
boolean required() default true;
......
/*
* 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.
......@@ -66,7 +66,7 @@ public @interface SessionAttribute {
* Whether the session attribute is required.
* <p>Defaults to {@code true}, leading to an exception being thrown
* if the attribute is missing in the session or there is no session.
* Switch this to {@code false} if you prefer a {@code null} or Java 1.8+
* Switch this to {@code false} if you prefer a {@code null} or Java 8
* {@code java.util.Optional} if the attribute doesn't exist.
*/
boolean required() default true;
......
......@@ -154,7 +154,6 @@ public class AsyncRestTemplate extends InterceptingAsyncHttpAccessor implements
/**
* Configure default URI variable values. This is a shortcut for:
* <pre class="code">
*
* DefaultUriTemplateHandler handler = new DefaultUriTemplateHandler();
* handler.setDefaultUriVariables(...);
*
......@@ -167,7 +166,7 @@ public class AsyncRestTemplate extends InterceptingAsyncHttpAccessor implements
public void setDefaultUriVariables(Map<String, ?> defaultUriVariables) {
UriTemplateHandler handler = this.syncTemplate.getUriTemplateHandler();
Assert.isInstanceOf(AbstractUriTemplateHandler.class, handler,
"Can only use this property in conjunction with a DefaultUriTemplateHandler.");
"Can only use this property in conjunction with a DefaultUriTemplateHandler");
((AbstractUriTemplateHandler) handler).setDefaultUriVariables(defaultUriVariables);
}
......
......@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.client;
import java.io.UnsupportedEncodingException;
......@@ -21,12 +22,12 @@ import java.nio.charset.Charset;
import org.springframework.http.HttpHeaders;
/**
* Abstract base class for exceptions that contain actual HTTP response data.
* Common base class for exceptions that contain actual HTTP response data.
*
* @author Rossen Stoyanchev
* @since 4.3
*/
public abstract class RestClientResponseException extends RestClientException {
public class RestClientResponseException extends RestClientException {
private static final long serialVersionUID = -8803556342728481792L;
......
......@@ -240,7 +240,6 @@ public class RestTemplate extends InterceptingHttpAccessor implements RestOperat
/**
* Configure default URI variable values. This is a shortcut for:
* <pre class="code">
*
* DefaultUriTemplateHandler handler = new DefaultUriTemplateHandler();
* handler.setDefaultUriVariables(...);
*
......@@ -252,7 +251,7 @@ public class RestTemplate extends InterceptingHttpAccessor implements RestOperat
*/
public void setDefaultUriVariables(Map<String, ?> defaultUriVariables) {
Assert.isInstanceOf(AbstractUriTemplateHandler.class, this.uriTemplateHandler,
"Can only use this property in conjunction with an AbstractUriTemplateHandler.");
"Can only use this property in conjunction with an AbstractUriTemplateHandler");
((AbstractUriTemplateHandler) this.uriTemplateHandler).setDefaultUriVariables(defaultUriVariables);
}
......
......@@ -63,6 +63,7 @@ public class ForwardedHeaderFilter extends OncePerRequestFilter {
FORWARDED_HEADER_NAMES.add("X-Forwarded-Prefix");
}
private final UrlPathHelper pathHelper = new UrlPathHelper();
......@@ -114,7 +115,6 @@ public class ForwardedHeaderFilter extends OncePerRequestFilter {
private final Map<String, List<String>> headers;
public ForwardedHeaderRequestWrapper(HttpServletRequest request, UrlPathHelper pathHelper) {
super(request);
......
......@@ -46,11 +46,12 @@ public abstract class MultipartResolutionDelegate {
static {
try {
servletPartClass = ClassUtils.forName(
"javax.servlet.http.Part", MultipartResolutionDelegate.class.getClassLoader());
servletPartClass = ClassUtils.forName("javax.servlet.http.Part",
MultipartResolutionDelegate.class.getClassLoader());
}
catch (ClassNotFoundException ex) {
// Servlet 3.0 Part type not available - Part references simply not supported then.
// Servlet 3.0 javax.servlet.http.Part type not available -
// Part references simply not supported then.
}
}
......
......@@ -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;
......@@ -106,6 +107,7 @@ public abstract class AbstractUriTemplateHandler implements UriTemplateHandler {
return insertBaseUrl(url);
}
/**
* Actually expand and encode the URI template.
*/
......@@ -116,13 +118,15 @@ public abstract class AbstractUriTemplateHandler implements UriTemplateHandler {
*/
protected abstract URI expandInternal(String uriTemplate, Object... uriVariables);
/**
* Insert a base URL (if configured) unless the given URL has a host already.
*/
private URI insertBaseUrl(URI url) {
try {
if (getBaseUrl() != null && url.getHost() == null) {
url = new URI(getBaseUrl() + url.toString());
String baseUrl = getBaseUrl();
if (baseUrl != null && url.getHost() == null) {
url = new URI(baseUrl + url.toString());
}
return url;
}
......
......@@ -51,7 +51,7 @@ public class ModelAndView {
/** Model Map */
private ModelMap model;
/** Optional status for the response */
/** Optional HTTP status for the response */
private HttpStatus status;
/** Indicates whether or not this instance has been cleared with a call to {@link #clear()} */
......@@ -120,7 +120,6 @@ public class ModelAndView {
}
}
/**
* Creates new ModelAndView given a view name, model, and status.
* @param viewName name of the View to render, to be resolved
......@@ -129,6 +128,7 @@ public class ModelAndView {
* (Objects). Model entries may not be {@code null}, but the
* model Map may be {@code null} if there is no model data.
* @param status an alternative status code to use for the response.
* @since 4.3
*/
public ModelAndView(String viewName, Map<String, ?> model, HttpStatus status) {
this.view = viewName;
......@@ -239,7 +239,7 @@ public class ModelAndView {
}
/**
* Set the status to use for the response.
* Set the HTTP status to use for the response.
* @since 4.3
*/
public void setStatus(HttpStatus status) {
......@@ -247,7 +247,8 @@ public class ModelAndView {
}
/**
* Return the configured status for the response.
* Return the configured HTTP status for the response, if any.
* @since 4.3
*/
public HttpStatus getStatus() {
return this.status;
......
......@@ -847,7 +847,7 @@ public class WebMvcConfigurationSupport implements ApplicationContextAware, Serv
* be useful for example to allow default resolvers to be registered and then
* insert a custom one through this method.
* @param exceptionResolvers the list of configured resolvers to extend.
* @since 4.3.1
* @since 4.3
*/
protected void extendHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers) {
}
......
......@@ -136,7 +136,7 @@ public interface WebMvcConfigurer {
* be useful for example to allow default resolvers to be registered and then
* insert a custom one through this method.
* @param exceptionResolvers the list of configured resolvers to extend.
* @since 4.3.1
* @since 4.3
*/
void extendHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers);
......
......@@ -40,7 +40,7 @@ import org.springframework.web.servlet.LocaleResolver;
*/
public class AcceptHeaderLocaleResolver implements LocaleResolver {
private final List<Locale> supportedLocales = new ArrayList<Locale>();
private final List<Locale> supportedLocales = new ArrayList<Locale>(4);
private Locale defaultLocale;
......@@ -91,8 +91,9 @@ public class AcceptHeaderLocaleResolver implements LocaleResolver {
@Override
public Locale resolveLocale(HttpServletRequest request) {
if (getDefaultLocale() != null && request.getHeader("Accept-Language") == null) {
return getDefaultLocale();
Locale defaultLocale = getDefaultLocale();
if (defaultLocale != null && request.getHeader("Accept-Language") == null) {
return defaultLocale;
}
Locale locale = request.getLocale();
if (!isSupportedLocale(locale)) {
......@@ -102,7 +103,8 @@ public class AcceptHeaderLocaleResolver implements LocaleResolver {
}
private boolean isSupportedLocale(Locale locale) {
return (getSupportedLocales().isEmpty() || getSupportedLocales().contains(locale));
List<Locale> supportedLocales = getSupportedLocales();
return (supportedLocales.isEmpty() || supportedLocales.contains(locale));
}
private Locale findSupportedLocale(HttpServletRequest request, Locale fallback) {
......
......@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.servlet.mvc.method.annotation;
import org.springframework.web.context.request.async.DeferredResult;
......@@ -27,7 +28,7 @@ public interface DeferredResultAdapter {
/**
* Create a {@code DeferredResult} for the given return value.
* @param returnValue the return value, never {@code null}
* @param returnValue the return value (never {@code null})
* @return the DeferredResult
*/
DeferredResult<?> adaptToDeferredResult(Object returnValue);
......
......@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.servlet.mvc.method.annotation;
import javax.servlet.ServletException;
......@@ -33,17 +34,15 @@ import org.springframework.web.method.annotation.AbstractNamedValueMethodArgumen
*/
public class RequestAttributeMethodArgumentResolver extends AbstractNamedValueMethodArgumentResolver {
@Override
public boolean supportsParameter(MethodParameter parameter) {
return parameter.hasParameterAnnotation(RequestAttribute.class);
}
@Override
protected NamedValueInfo createNamedValueInfo(MethodParameter parameter) {
RequestAttribute annot = parameter.getParameterAnnotation(RequestAttribute.class);
return new NamedValueInfo(annot.name(), annot.required(), ValueConstants.DEFAULT_NONE);
RequestAttribute ann = parameter.getParameterAnnotation(RequestAttribute.class);
return new NamedValueInfo(ann.name(), ann.required(), ValueConstants.DEFAULT_NONE);
}
@Override
......
......@@ -13,23 +13,24 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.servlet.mvc.method.annotation;
import org.springframework.http.server.ServerHttpResponse;
/**
* Contract to adapt streaming async types to {@code ResponseBodyEmitter}.
*
* @author Rossen Stoyanchev
* @since 4.3
*/
public interface ResponseBodyEmitterAdapter {
/**
* Obtain a {@code ResponseBodyEmitter} for the given return value. If
* the return is the body {@code ResponseEntity} then the given
* Obtain a {@code ResponseBodyEmitter} for the given return value.
* If the return is the body {@code ResponseEntity} then the given
* {@code ServerHttpResponse} contains its status and headers.
* @param returnValue the return value, never {@code null}
* @param returnValue the return value (never {@code null})
* @param response the response
* @return the return value adapted to a {@code ResponseBodyEmitter}
*/
......
......@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.servlet.mvc.method.annotation;
import javax.servlet.ServletException;
......@@ -33,17 +34,15 @@ import org.springframework.web.method.annotation.AbstractNamedValueMethodArgumen
*/
public class SessionAttributeMethodArgumentResolver extends AbstractNamedValueMethodArgumentResolver {
@Override
public boolean supportsParameter(MethodParameter parameter) {
return parameter.hasParameterAnnotation(SessionAttribute.class);
}
@Override
protected NamedValueInfo createNamedValueInfo(MethodParameter parameter) {
SessionAttribute annot = parameter.getParameterAnnotation(SessionAttribute.class);
return new NamedValueInfo(annot.name(), annot.required(), ValueConstants.DEFAULT_NONE);
SessionAttribute ann = parameter.getParameterAnnotation(SessionAttribute.class);
return new NamedValueInfo(ann.name(), ann.required(), ValueConstants.DEFAULT_NONE);
}
@Override
......
......@@ -145,27 +145,6 @@ public abstract class WebContentGenerator extends WebApplicationObjectSupport {
setSupportedMethods(supportedMethods);
}
private void initAllowHeader() {
Collection<String> allowedMethods;
if (this.supportedMethods == null) {
allowedMethods = new ArrayList<String>(HttpMethod.values().length - 1);
for (HttpMethod method : HttpMethod.values()) {
if (!HttpMethod.TRACE.equals(method)) {
allowedMethods.add(method.name());
}
}
}
else if (this.supportedMethods.contains(HttpMethod.OPTIONS.name())) {
allowedMethods = this.supportedMethods;
}
else {
allowedMethods = new ArrayList<String>(this.supportedMethods);
allowedMethods.add(HttpMethod.OPTIONS.name());
}
this.allowHeader = StringUtils.collectionToCommaDelimitedString(allowedMethods);
}
/**
* Set the HTTP methods that this content generator should support.
......@@ -189,6 +168,27 @@ public abstract class WebContentGenerator extends WebApplicationObjectSupport {
return StringUtils.toStringArray(this.supportedMethods);
}
private void initAllowHeader() {
Collection<String> allowedMethods;
if (this.supportedMethods == null) {
allowedMethods = new ArrayList<String>(HttpMethod.values().length - 1);
for (HttpMethod method : HttpMethod.values()) {
if (!HttpMethod.TRACE.equals(method)) {
allowedMethods.add(method.name());
}
}
}
else if (this.supportedMethods.contains(HttpMethod.OPTIONS.name())) {
allowedMethods = this.supportedMethods;
}
else {
allowedMethods = new ArrayList<String>(this.supportedMethods);
allowedMethods.add(HttpMethod.OPTIONS.name());
}
this.allowHeader = StringUtils.collectionToCommaDelimitedString(allowedMethods);
}
/**
* Return the "Allow" header value to use in response to an HTTP OPTIONS
* request based on the configured {@link #setSupportedMethods supported
......@@ -268,14 +268,15 @@ public abstract class WebContentGenerator extends WebApplicationObjectSupport {
* @param varyByRequestHeaders one or more request header names
* @since 4.3
*/
public void setVaryByRequestHeaders(String... varyByRequestHeaders) {
public final void setVaryByRequestHeaders(String... varyByRequestHeaders) {
this.varyByRequestHeaders = varyByRequestHeaders;
}
/**
* Return the configured request header names for the "Vary" response header.
* @since 4.3
*/
public String[] getVaryByRequestHeaders() {
public final String[] getVaryByRequestHeaders() {
return this.varyByRequestHeaders;
}
......@@ -593,6 +594,7 @@ public abstract class WebContentGenerator extends WebApplicationObjectSupport {
}
}
private Collection<String> getVaryRequestHeadersToAdd(HttpServletResponse response) {
if (!response.containsHeader(HttpHeaders.VARY)) {
return Arrays.asList(getVaryByRequestHeaders());
......
/*
* 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,21 +255,22 @@ public class RedirectView extends AbstractUrlBasedView implements SmartView {
}
/**
* Configure one or more hosts associated with the application. All other
* hosts will be considered external hosts. In effect this property
* provides a way turn off encoding via
* {@link HttpServletResponse#encodeRedirectURL} for URLs that have a host
* and that host is not listed as a known host.
* Configure one or more hosts associated with the application.
* All other hosts will be considered external hosts.
* <p>In effect, this property provides a way turn off encoding via
* {@link HttpServletResponse#encodeRedirectURL} for URLs that have a
* host and that host is not listed as a known host.
* <p>If not set (the default) all URLs are encoded through the response.
* @param hosts one or more application hosts
* @since 4.3
*/
public void setHosts(String[] hosts) {
public void setHosts(String... hosts) {
this.hosts = hosts;
}
/**
* Return the configured application hosts.
* @since 4.3
*/
public String[] getHosts() {
return this.hosts;
......
......@@ -257,21 +257,22 @@ public class UrlBasedViewResolver extends AbstractCachingViewResolver implements
}
/**
* Configure one or more hosts associated with the application. All other
* hosts will be considered external hosts. In effect this property
* provides a way turn off encoding on redirect via
* {@link HttpServletResponse#encodeRedirectURL} for URLs that have a host
* and that host is not listed as a known host.
* Configure one or more hosts associated with the application.
* All other hosts will be considered external hosts.
* <p>In effect, this property provides a way turn off encoding on redirect
* via {@link HttpServletResponse#encodeRedirectURL} for URLs that have a
* host and that host is not listed as a known host.
* <p>If not set (the default) all URLs are encoded through the response.
* @param redirectHosts one or more application hosts
* @since 4.3
*/
public void setRedirectHosts(String[] redirectHosts) {
public void setRedirectHosts(String... redirectHosts) {
this.redirectHosts = redirectHosts;
}
/**
* Return the configured application hosts for redirect purposes.
* @since 4.3
*/
public String[] getRedirectHosts() {
return this.redirectHosts;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册