SPR-7354 - Added equivalent of JAX-RS @Consumes to Spring MVC
This commit is contained in:
parent
7f247a6b27
commit
71aae405d5
|
|
@ -24,7 +24,6 @@ import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
import org.springframework.core.annotation.AnnotationUtils;
|
import org.springframework.core.annotation.AnnotationUtils;
|
||||||
|
|
@ -128,7 +127,7 @@ public class RequestMappingHandlerMapping extends AbstractHandlerMethodMapping<R
|
||||||
return new RequestMappingInfo(Arrays.asList(annotation.value()), Arrays.asList(annotation.method()),
|
return new RequestMappingInfo(Arrays.asList(annotation.value()), Arrays.asList(annotation.method()),
|
||||||
RequestConditionFactory.parseParams(annotation.params()),
|
RequestConditionFactory.parseParams(annotation.params()),
|
||||||
RequestConditionFactory.parseHeaders(annotation.headers()),
|
RequestConditionFactory.parseHeaders(annotation.headers()),
|
||||||
RequestConditionFactory.parseConsumes());
|
RequestConditionFactory.parseConsumes(annotation.consumes(), annotation.headers()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -240,6 +239,10 @@ public class RequestMappingHandlerMapping extends AbstractHandlerMethodMapping<R
|
||||||
if (result != 0) {
|
if (result != 0) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
result = mapping.getConsumes().compareTo(otherMapping.getConsumes());
|
||||||
|
if (result != 0) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
TODO: fix
|
TODO: fix
|
||||||
result = compareAcceptHeaders(mapping.getAcceptHeaderMediaTypes(), otherMapping.getAcceptHeaderMediaTypes());
|
result = compareAcceptHeaders(mapping.getAcceptHeaderMediaTypes(), otherMapping.getAcceptHeaderMediaTypes());
|
||||||
|
|
|
||||||
|
|
@ -22,14 +22,14 @@ import java.util.Collections;
|
||||||
import java.util.LinkedHashSet;
|
import java.util.LinkedHashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
import org.springframework.util.PathMatcher;
|
import org.springframework.util.PathMatcher;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
import org.springframework.web.bind.annotation.RequestMethod;
|
import org.springframework.web.bind.annotation.RequestMethod;
|
||||||
import org.springframework.web.servlet.mvc.method.condition.RequestCondition;
|
import org.springframework.web.servlet.mvc.method.condition.ConsumesRequestCondition;
|
||||||
import org.springframework.web.servlet.mvc.method.condition.RequestConditionFactory;
|
import org.springframework.web.servlet.mvc.method.condition.HeadersRequestCondition;
|
||||||
|
import org.springframework.web.servlet.mvc.method.condition.ParamsRequestCondition;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Contains a set of conditions to match to a given request such as URL patterns, HTTP methods, request parameters
|
* Contains a set of conditions to match to a given request such as URL patterns, HTTP methods, request parameters
|
||||||
|
|
@ -49,16 +49,16 @@ public final class RequestMappingInfo {
|
||||||
|
|
||||||
private final Set<RequestMethod> methods;
|
private final Set<RequestMethod> methods;
|
||||||
|
|
||||||
private final RequestCondition paramsCondition;
|
private final ParamsRequestCondition paramsCondition;
|
||||||
|
|
||||||
private final RequestCondition headersCondition;
|
private final HeadersRequestCondition headersCondition;
|
||||||
|
|
||||||
private final RequestCondition consumesCondition;
|
private final ConsumesRequestCondition consumesCondition;
|
||||||
|
|
||||||
private int hash;
|
private int hash;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new {@code RequestKey} instance with the given URL patterns and HTTP methods.
|
* Creates a new {@code RequestMappingInfo} instance with the given URL patterns and HTTP methods.
|
||||||
*
|
*
|
||||||
* <p>Package protected for testing purposes.
|
* <p>Package protected for testing purposes.
|
||||||
*/
|
*/
|
||||||
|
|
@ -67,18 +67,18 @@ public final class RequestMappingInfo {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new {@code RequestKey} instance with a full set of conditions.
|
* Creates a new {@code RequestMappingInfo} instance with a full set of conditions.
|
||||||
*/
|
*/
|
||||||
public RequestMappingInfo(Collection<String> patterns,
|
public RequestMappingInfo(Collection<String> patterns,
|
||||||
Collection<RequestMethod> methods,
|
Collection<RequestMethod> methods,
|
||||||
RequestCondition paramsCondition,
|
ParamsRequestCondition paramsCondition,
|
||||||
RequestCondition headersCondition,
|
HeadersRequestCondition headersCondition,
|
||||||
RequestCondition consumesCondition) {
|
ConsumesRequestCondition consumesCondition) {
|
||||||
this.patterns = asUnmodifiableSet(prependLeadingSlash(patterns));
|
this.patterns = asUnmodifiableSet(prependLeadingSlash(patterns));
|
||||||
this.methods = asUnmodifiableSet(methods);
|
this.methods = asUnmodifiableSet(methods);
|
||||||
this.paramsCondition = paramsCondition != null ? paramsCondition : RequestConditionFactory.trueCondition();
|
this.paramsCondition = paramsCondition != null ? paramsCondition : new ParamsRequestCondition();
|
||||||
this.headersCondition = headersCondition != null ? headersCondition : RequestConditionFactory.trueCondition();
|
this.headersCondition = headersCondition != null ? headersCondition : new HeadersRequestCondition();
|
||||||
this.consumesCondition = consumesCondition != null ? consumesCondition : RequestConditionFactory.trueCondition();
|
this.consumesCondition = consumesCondition != null ? consumesCondition : new ConsumesRequestCondition();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Set<String> prependLeadingSlash(Collection<String> patterns) {
|
private static Set<String> prependLeadingSlash(Collection<String> patterns) {
|
||||||
|
|
@ -118,21 +118,28 @@ public final class RequestMappingInfo {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the request parameters of this request key.
|
* Returns the request parameters conditions of this request key.
|
||||||
*/
|
*/
|
||||||
public RequestCondition getParams() {
|
public ParamsRequestCondition getParams() {
|
||||||
return paramsCondition;
|
return paramsCondition;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the request headers of this request key.
|
* Returns the request headers conditions of this request key.
|
||||||
*/
|
*/
|
||||||
public RequestCondition getHeaders() {
|
public HeadersRequestCondition getHeaders() {
|
||||||
return headersCondition;
|
return headersCondition;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Combines this {@code RequestKey} with another as follows:
|
* Returns the request consumes conditions of this request key.
|
||||||
|
*/
|
||||||
|
public ConsumesRequestCondition getConsumes() {
|
||||||
|
return consumesCondition;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Combines this {@code RequestMappingInfo} with another as follows:
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>URL patterns:
|
* <li>URL patterns:
|
||||||
* <ul>
|
* <ul>
|
||||||
|
|
@ -141,9 +148,9 @@ public final class RequestMappingInfo {
|
||||||
* <li>If neither contains patterns use ""
|
* <li>If neither contains patterns use ""
|
||||||
* </ul>
|
* </ul>
|
||||||
* <li>HTTP methods are combined as union of all HTTP methods listed in both keys.
|
* <li>HTTP methods are combined as union of all HTTP methods listed in both keys.
|
||||||
* <li>Request parameter are combined into a logical AND.
|
* <li>Request parameters are combined as per {@link ParamsRequestCondition#combine(ParamsRequestCondition)}.
|
||||||
* <li>Request header are combined into a logical AND.
|
* <li>Request headers are combined as per {@link HeadersRequestCondition#combine(HeadersRequestCondition)}.
|
||||||
* <li>Consumes .. TODO
|
* <li>Consumes are combined as per {@link ConsumesRequestCondition#combine(ConsumesRequestCondition)}.
|
||||||
* </ul>
|
* </ul>
|
||||||
* @param methodKey the key to combine with
|
* @param methodKey the key to combine with
|
||||||
* @param pathMatcher to {@linkplain PathMatcher#combine(String, String) combine} the patterns
|
* @param pathMatcher to {@linkplain PathMatcher#combine(String, String) combine} the patterns
|
||||||
|
|
@ -152,9 +159,9 @@ public final class RequestMappingInfo {
|
||||||
public RequestMappingInfo combine(RequestMappingInfo methodKey, PathMatcher pathMatcher) {
|
public RequestMappingInfo combine(RequestMappingInfo methodKey, PathMatcher pathMatcher) {
|
||||||
Set<String> patterns = combinePatterns(this.patterns, methodKey.patterns, pathMatcher);
|
Set<String> patterns = combinePatterns(this.patterns, methodKey.patterns, pathMatcher);
|
||||||
Set<RequestMethod> methods = union(this.methods, methodKey.methods);
|
Set<RequestMethod> methods = union(this.methods, methodKey.methods);
|
||||||
RequestCondition params = RequestConditionFactory.and(this.paramsCondition, methodKey.paramsCondition);
|
ParamsRequestCondition params = this.paramsCondition.combine(methodKey.paramsCondition);
|
||||||
RequestCondition headers = RequestConditionFactory.and(this.headersCondition, methodKey.headersCondition);
|
HeadersRequestCondition headers = this.headersCondition.combine(methodKey.headersCondition);
|
||||||
RequestCondition consumes = RequestConditionFactory.mostSpecific(methodKey.consumesCondition, this.consumesCondition);
|
ConsumesRequestCondition consumes = this.consumesCondition.combine(methodKey.consumesCondition);
|
||||||
|
|
||||||
return new RequestMappingInfo(patterns, methods, params, headers, consumes);
|
return new RequestMappingInfo(patterns, methods, params, headers, consumes);
|
||||||
}
|
}
|
||||||
|
|
@ -189,7 +196,7 @@ public final class RequestMappingInfo {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a new {@code RequestKey} that contains all conditions of this key that are relevant to the request.
|
* Returns a new {@code RequestMappingInfo} that contains all conditions of this key that are relevant to the request.
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>The list of URL path patterns is trimmed to contain the patterns that match the URL with matching patterns
|
* <li>The list of URL path patterns is trimmed to contain the patterns that match the URL with matching patterns
|
||||||
* sorted via {@link PathMatcher#getPatternComparator(String)}.
|
* sorted via {@link PathMatcher#getPatternComparator(String)}.
|
||||||
|
|
@ -203,16 +210,20 @@ public final class RequestMappingInfo {
|
||||||
* @return a new request key that contains all matching attributes, or {@code null} if not all conditions match
|
* @return a new request key that contains all matching attributes, or {@code null} if not all conditions match
|
||||||
*/
|
*/
|
||||||
public RequestMappingInfo getMatchingRequestMapping(String lookupPath, HttpServletRequest request, PathMatcher pathMatcher) {
|
public RequestMappingInfo getMatchingRequestMapping(String lookupPath, HttpServletRequest request, PathMatcher pathMatcher) {
|
||||||
if (!checkMethod(request) || !paramsCondition.match(request) || !headersCondition.match(request) ||
|
ParamsRequestCondition matchingParamsCondition = paramsCondition.getMatchingCondition(request);
|
||||||
!consumesCondition.match(request)) {
|
HeadersRequestCondition matchingHeadersCondition = headersCondition.getMatchingCondition(request);
|
||||||
|
ConsumesRequestCondition matchingConsumesCondition = consumesCondition.getMatchingCondition(request);
|
||||||
|
|
||||||
|
if (!checkMethod(request) || matchingParamsCondition == null || matchingHeadersCondition == null ||
|
||||||
|
matchingConsumesCondition == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
List<String> matchingPatterns = getMatchingPatterns(lookupPath, request, pathMatcher);
|
List<String> matchingPatterns = getMatchingPatterns(lookupPath, request, pathMatcher);
|
||||||
if (!matchingPatterns.isEmpty()) {
|
if (!matchingPatterns.isEmpty()) {
|
||||||
Set<RequestMethod> matchingMethods = getMatchingMethod(request);
|
Set<RequestMethod> matchingMethods = getMatchingMethod(request);
|
||||||
return new RequestMappingInfo(matchingPatterns, matchingMethods, this.paramsCondition, this.headersCondition,
|
return new RequestMappingInfo(matchingPatterns, matchingMethods, matchingParamsCondition,
|
||||||
this.consumesCondition);
|
matchingHeadersCondition, matchingConsumesCondition);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return null;
|
return null;
|
||||||
|
|
@ -277,7 +288,8 @@ public final class RequestMappingInfo {
|
||||||
RequestMappingInfo other = (RequestMappingInfo) obj;
|
RequestMappingInfo other = (RequestMappingInfo) obj;
|
||||||
return (this.patterns.equals(other.patterns) && this.methods.equals(other.methods) &&
|
return (this.patterns.equals(other.patterns) && this.methods.equals(other.methods) &&
|
||||||
this.paramsCondition.equals(other.paramsCondition) &&
|
this.paramsCondition.equals(other.paramsCondition) &&
|
||||||
this.headersCondition.equals(other.headersCondition));
|
this.headersCondition.equals(other.headersCondition) &&
|
||||||
|
this.consumesCondition.equals(other.consumesCondition));
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -290,6 +302,7 @@ public final class RequestMappingInfo {
|
||||||
result = 31 * result + methods.hashCode();
|
result = 31 * result + methods.hashCode();
|
||||||
result = 31 * result + paramsCondition.hashCode();
|
result = 31 * result + paramsCondition.hashCode();
|
||||||
result = 31 * result + headersCondition.hashCode();
|
result = 31 * result + headersCondition.hashCode();
|
||||||
|
result = 31 * result + consumesCondition.hashCode();
|
||||||
hash = result;
|
hash = result;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ import javax.servlet.http.HttpServletRequest;
|
||||||
* @author Arjen Poutsma
|
* @author Arjen Poutsma
|
||||||
* @since 3.1
|
* @since 3.1
|
||||||
*/
|
*/
|
||||||
abstract class AbstractNameValueCondition<T> extends AbstractRequestCondition {
|
abstract class AbstractNameValueCondition<T> implements RequestCondition {
|
||||||
|
|
||||||
protected final String name;
|
protected final String name;
|
||||||
|
|
||||||
|
|
@ -65,11 +65,6 @@ abstract class AbstractNameValueCondition<T> extends AbstractRequestCondition {
|
||||||
|
|
||||||
protected abstract boolean matchValue(HttpServletRequest request);
|
protected abstract boolean matchValue(HttpServletRequest request);
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getSpecificity() {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
int result = name.hashCode();
|
int result = name.hashCode();
|
||||||
|
|
|
||||||
|
|
@ -1,41 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2002-2011 the original author or authors.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.springframework.web.servlet.mvc.method.condition;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Abstract base class for {@link RequestCondition} that provides a standard {@link Comparable} implementation based on
|
|
||||||
* the conditions {@linkplain #getSpecificity() specificity}.
|
|
||||||
*
|
|
||||||
* @author Arjen Poutsma
|
|
||||||
* @since 3.1
|
|
||||||
*/
|
|
||||||
public abstract class AbstractRequestCondition implements RequestCondition {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the conditions specificity. More specific conditions should return a higher value than ones which are less
|
|
||||||
* so.
|
|
||||||
*
|
|
||||||
* @return the conditions specificity
|
|
||||||
*/
|
|
||||||
protected abstract int getSpecificity();
|
|
||||||
|
|
||||||
public int compareTo(RequestCondition o) {
|
|
||||||
AbstractRequestCondition other = (AbstractRequestCondition) o;
|
|
||||||
return other.getSpecificity() - this.getSpecificity();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -16,36 +16,158 @@
|
||||||
|
|
||||||
package org.springframework.web.servlet.mvc.method.condition;
|
package org.springframework.web.servlet.mvc.method.condition;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.LinkedHashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Represents a collection of consumes conditions, typically obtained from {@link
|
||||||
|
* org.springframework.web.bind.annotation.RequestMapping#consumes() @RequestMapping.consumes()}.
|
||||||
|
*
|
||||||
* @author Arjen Poutsma
|
* @author Arjen Poutsma
|
||||||
|
* @see RequestConditionFactory#parseHeaders(String...)
|
||||||
|
* @since 3.1
|
||||||
*/
|
*/
|
||||||
class ConsumesRequestCondition extends AbstractRequestCondition {
|
public class ConsumesRequestCondition
|
||||||
|
extends LogicalDisjunctionRequestCondition<ConsumesRequestCondition.ConsumeRequestCondition>
|
||||||
|
implements Comparable<ConsumesRequestCondition> {
|
||||||
|
|
||||||
|
private final ConsumeRequestCondition mostSpecificCondition;
|
||||||
|
|
||||||
|
ConsumesRequestCondition(Collection<ConsumeRequestCondition> conditions) {
|
||||||
|
super(conditions);
|
||||||
|
Assert.notEmpty(conditions, "'conditions' must not be empty");
|
||||||
|
mostSpecificCondition = getMostSpecificCondition();
|
||||||
|
}
|
||||||
|
|
||||||
|
private ConsumeRequestCondition getMostSpecificCondition() {
|
||||||
|
List<ConsumeRequestCondition> conditions = new ArrayList<ConsumeRequestCondition>(getConditions());
|
||||||
|
Collections.sort(conditions);
|
||||||
|
return conditions.get(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
ConsumesRequestCondition(String... consumes) {
|
||||||
|
this(parseConditions(Arrays.asList(consumes)));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Set<ConsumeRequestCondition> parseConditions(List<String> consumes) {
|
||||||
|
if (consumes.isEmpty()) {
|
||||||
|
consumes = Collections.singletonList("*/*");
|
||||||
|
}
|
||||||
|
Set<ConsumeRequestCondition> conditions = new LinkedHashSet<ConsumeRequestCondition>(consumes.size());
|
||||||
|
for (String consume : consumes) {
|
||||||
|
conditions.add(new ConsumeRequestCondition(consume));
|
||||||
|
}
|
||||||
|
return conditions;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an default set of consumes request conditions.
|
||||||
|
*/
|
||||||
|
public ConsumesRequestCondition() {
|
||||||
|
this(Collections.singleton(new ConsumeRequestCondition(MediaType.ALL, false)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a new {@code RequestCondition} that contains all conditions of this key that match the request.
|
||||||
|
*
|
||||||
|
* @param request the request
|
||||||
|
* @return a new request condition that contains all matching attributes, or {@code null} if not all conditions match
|
||||||
|
*/
|
||||||
|
public ConsumesRequestCondition getMatchingCondition(HttpServletRequest request) {
|
||||||
|
Set<ConsumeRequestCondition> matchingConditions = new LinkedHashSet<ConsumeRequestCondition>(getConditions());
|
||||||
|
for (Iterator<ConsumeRequestCondition> iterator = matchingConditions.iterator(); iterator.hasNext();) {
|
||||||
|
ConsumeRequestCondition condition = iterator.next();
|
||||||
|
if (!condition.match(request)) {
|
||||||
|
iterator.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (matchingConditions.isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return new ConsumesRequestCondition(matchingConditions);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Combines this collection of request condition with another. Returns {@code other}, unless it has the default
|
||||||
|
* value (i.e. <code>*/*</code>).
|
||||||
|
*
|
||||||
|
* @param other the condition to combine with
|
||||||
|
*/
|
||||||
|
public ConsumesRequestCondition combine(ConsumesRequestCondition other) {
|
||||||
|
return !other.hasDefaultValue() ? other : this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean hasDefaultValue() {
|
||||||
|
Set<ConsumeRequestCondition> conditions = getConditions();
|
||||||
|
if (conditions.size() == 1) {
|
||||||
|
ConsumeRequestCondition condition = conditions.iterator().next();
|
||||||
|
return condition.getMediaType().equals(MediaType.ALL);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int compareTo(ConsumesRequestCondition other) {
|
||||||
|
return this.mostSpecificCondition.compareTo(other.mostSpecificCondition);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static MediaType getContentType(HttpServletRequest request) {
|
||||||
|
if (StringUtils.hasLength(request.getContentType())) {
|
||||||
|
return MediaType.parseMediaType(request.getContentType());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return MediaType.APPLICATION_OCTET_STREAM;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class ConsumeRequestCondition implements RequestCondition, Comparable<ConsumeRequestCondition> {
|
||||||
|
|
||||||
private final MediaType mediaType;
|
private final MediaType mediaType;
|
||||||
|
|
||||||
ConsumesRequestCondition(String mediaType) {
|
private final boolean isNegated;
|
||||||
this.mediaType = MediaType.parseMediaType(mediaType);
|
|
||||||
|
ConsumeRequestCondition(String expression) {
|
||||||
|
if (expression.startsWith("!")) {
|
||||||
|
isNegated = true;
|
||||||
|
expression = expression.substring(1);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
isNegated = false;
|
||||||
|
}
|
||||||
|
this.mediaType = MediaType.parseMediaType(expression);
|
||||||
|
}
|
||||||
|
|
||||||
|
ConsumeRequestCondition(MediaType mediaType, boolean isNegated) {
|
||||||
|
this.mediaType = mediaType;
|
||||||
|
this.isNegated = isNegated;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean match(HttpServletRequest request) {
|
public boolean match(HttpServletRequest request) {
|
||||||
MediaType contentType;
|
MediaType contentType = getContentType(request);
|
||||||
if (StringUtils.hasLength(request.getContentType())) {
|
boolean match = this.mediaType.includes(contentType);
|
||||||
contentType = MediaType.parseMediaType(request.getContentType());
|
return !isNegated ? match : !match;
|
||||||
}
|
|
||||||
else {
|
|
||||||
contentType = MediaType.APPLICATION_OCTET_STREAM;
|
|
||||||
}
|
|
||||||
return this.mediaType.includes(contentType);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public int compareTo(ConsumeRequestCondition other) {
|
||||||
public int getSpecificity() {
|
return MediaType.SPECIFICITY_COMPARATOR.compare(this.mediaType, other.mediaType);
|
||||||
return 1;
|
}
|
||||||
|
|
||||||
|
MediaType getMediaType() {
|
||||||
|
return mediaType;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -53,20 +175,27 @@ class ConsumesRequestCondition extends AbstractRequestCondition {
|
||||||
if (this == obj) {
|
if (this == obj) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (obj != null && obj instanceof ConsumesRequestCondition) {
|
if (obj != null && obj instanceof ConsumeRequestCondition) {
|
||||||
ConsumesRequestCondition other = (ConsumesRequestCondition) obj;
|
ConsumeRequestCondition other = (ConsumeRequestCondition) obj;
|
||||||
return this.mediaType.equals(other.mediaType);
|
return (this.mediaType.equals(other.mediaType)) && (this.isNegated == other.isNegated);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return mediaType.hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
StringBuilder builder = new StringBuilder();
|
StringBuilder builder = new StringBuilder();
|
||||||
if (mediaType != null) {
|
if (isNegated) {
|
||||||
builder.append(mediaType.toString());
|
builder.append('!');
|
||||||
}
|
}
|
||||||
|
builder.append(mediaType.toString());
|
||||||
return builder.toString();
|
return builder.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,64 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2002-2011 the original author or authors.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.springframework.web.servlet.mvc.method.condition;
|
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Request header name-value condition.
|
|
||||||
*
|
|
||||||
* @author Rossen Stoyanchev
|
|
||||||
* @author Arjen Poutsma
|
|
||||||
* @see org.springframework.web.bind.annotation.RequestMapping#headers()
|
|
||||||
* @since 3.1
|
|
||||||
*/
|
|
||||||
class HeaderRequestCondition extends AbstractNameValueCondition<String> {
|
|
||||||
|
|
||||||
public HeaderRequestCondition(String expression) {
|
|
||||||
super(expression);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected String parseValue(String valueExpression) {
|
|
||||||
return valueExpression;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean matchName(HttpServletRequest request) {
|
|
||||||
return request.getHeader(name) != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean matchValue(HttpServletRequest request) {
|
|
||||||
return value.equals(request.getHeader(name));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object obj) {
|
|
||||||
if (this == obj) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (obj != null && obj instanceof HeaderRequestCondition) {
|
|
||||||
HeaderRequestCondition other = (HeaderRequestCondition) obj;
|
|
||||||
return ((this.name.equalsIgnoreCase(other.name)) &&
|
|
||||||
(this.value != null ? this.value.equals(other.value) : other.value == null) &&
|
|
||||||
this.isNegated == other.isNegated);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,134 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2002-2011 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.springframework.web.servlet.mvc.method.condition;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.LinkedHashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a collection of header request conditions, typically obtained from {@link
|
||||||
|
* org.springframework.web.bind.annotation.RequestMapping#headers() @RequestMapping.headers()}.
|
||||||
|
*
|
||||||
|
* @author Arjen Poutsma
|
||||||
|
* @see RequestConditionFactory#parseHeaders(String...)
|
||||||
|
* @since 3.1
|
||||||
|
*/
|
||||||
|
public class HeadersRequestCondition
|
||||||
|
extends LogicalConjunctionRequestCondition<HeadersRequestCondition.HeaderRequestCondition>
|
||||||
|
implements Comparable<HeadersRequestCondition> {
|
||||||
|
|
||||||
|
HeadersRequestCondition(Collection<HeaderRequestCondition> conditions) {
|
||||||
|
super(conditions);
|
||||||
|
}
|
||||||
|
|
||||||
|
HeadersRequestCondition(String... headers) {
|
||||||
|
this(parseConditions(Arrays.asList(headers)));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Set<HeaderRequestCondition> parseConditions(Collection<String> params) {
|
||||||
|
Set<HeaderRequestCondition> conditions = new LinkedHashSet<HeaderRequestCondition>(params.size());
|
||||||
|
for (String param : params) {
|
||||||
|
conditions.add(new HeaderRequestCondition(param));
|
||||||
|
}
|
||||||
|
return conditions;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an empty set of header request conditions.
|
||||||
|
*/
|
||||||
|
public HeadersRequestCondition() {
|
||||||
|
this(Collections.<HeaderRequestCondition>emptySet());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a new {@code RequestCondition} that contains all conditions of this key that match the request.
|
||||||
|
*
|
||||||
|
* @param request the request
|
||||||
|
* @return a new request condition that contains all matching attributes, or {@code null} if not all conditions match
|
||||||
|
*/
|
||||||
|
public HeadersRequestCondition getMatchingCondition(HttpServletRequest request) {
|
||||||
|
return match(request) ? this : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Combines this collection of request condition with another by combining all header request conditions into a
|
||||||
|
* logical AND.
|
||||||
|
*
|
||||||
|
* @param other the condition to combine with
|
||||||
|
*/
|
||||||
|
public HeadersRequestCondition combine(HeadersRequestCondition other) {
|
||||||
|
Set<HeaderRequestCondition> conditions = new LinkedHashSet<HeaderRequestCondition>(getConditions());
|
||||||
|
conditions.addAll(other.getConditions());
|
||||||
|
return new HeadersRequestCondition(conditions);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public int compareTo(HeadersRequestCondition other) {
|
||||||
|
return other.getConditions().size() - this.getConditions().size();
|
||||||
|
}
|
||||||
|
|
||||||
|
static class HeaderRequestCondition extends AbstractNameValueCondition<String> {
|
||||||
|
|
||||||
|
public HeaderRequestCondition(String expression) {
|
||||||
|
super(expression);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String parseValue(String valueExpression) {
|
||||||
|
return valueExpression;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean matchName(HttpServletRequest request) {
|
||||||
|
return request.getHeader(name) != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean matchValue(HttpServletRequest request) {
|
||||||
|
return value.equals(request.getHeader(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (obj != null && obj instanceof HeaderRequestCondition) {
|
||||||
|
HeaderRequestCondition other = (HeaderRequestCondition) obj;
|
||||||
|
return ((this.name.equalsIgnoreCase(other.name)) &&
|
||||||
|
(this.value != null ? this.value.equals(other.value) : other.value == null) &&
|
||||||
|
this.isNegated == other.isNegated);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int result = name.toLowerCase().hashCode();
|
||||||
|
result = 31 * result + (value != null ? value.hashCode() : 0);
|
||||||
|
result = 31 * result + (isNegated ? 1 : 0);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -16,7 +16,8 @@
|
||||||
|
|
||||||
package org.springframework.web.servlet.mvc.method.condition;
|
package org.springframework.web.servlet.mvc.method.condition;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.Collection;
|
||||||
|
import java.util.Set;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -25,14 +26,18 @@ import javax.servlet.http.HttpServletRequest;
|
||||||
* @author Arjen Poutsma
|
* @author Arjen Poutsma
|
||||||
* @since 3.1
|
* @since 3.1
|
||||||
*/
|
*/
|
||||||
class LogicalConjunctionRequestCondition extends RequestConditionComposite {
|
class LogicalConjunctionRequestCondition<T extends RequestCondition> extends RequestConditionComposite<T> {
|
||||||
|
|
||||||
LogicalConjunctionRequestCondition(List<RequestCondition> conditions) {
|
LogicalConjunctionRequestCondition(Collection<T> conditions) {
|
||||||
super(conditions);
|
super(conditions);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean match(HttpServletRequest request) {
|
public boolean match(HttpServletRequest request) {
|
||||||
for (RequestCondition condition : conditions) {
|
Set<T> conditions = getConditions();
|
||||||
|
if (conditions.isEmpty()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
for (T condition : conditions) {
|
||||||
if (!condition.match(request)) {
|
if (!condition.match(request)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -40,6 +45,7 @@ class LogicalConjunctionRequestCondition extends RequestConditionComposite {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected String getToStringInfix() {
|
protected String getToStringInfix() {
|
||||||
return " && ";
|
return " && ";
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
|
|
||||||
package org.springframework.web.servlet.mvc.method.condition;
|
package org.springframework.web.servlet.mvc.method.condition;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.Collection;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -25,14 +25,14 @@ import javax.servlet.http.HttpServletRequest;
|
||||||
* @author Arjen Poutsma
|
* @author Arjen Poutsma
|
||||||
* @since 3.1
|
* @since 3.1
|
||||||
*/
|
*/
|
||||||
class LogicalDisjunctionRequestCondition extends RequestConditionComposite {
|
class LogicalDisjunctionRequestCondition<T extends RequestCondition> extends RequestConditionComposite<T> {
|
||||||
|
|
||||||
LogicalDisjunctionRequestCondition(List<RequestCondition> conditions) {
|
LogicalDisjunctionRequestCondition(Collection<T> conditions) {
|
||||||
super(conditions);
|
super(conditions);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean match(HttpServletRequest request) {
|
public boolean match(HttpServletRequest request) {
|
||||||
for (RequestCondition condition : conditions) {
|
for (RequestCondition condition : getConditions()) {
|
||||||
if (condition.match(request)) {
|
if (condition.match(request)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,73 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2002-2011 the original author or authors.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.springframework.web.servlet.mvc.method.condition;
|
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
|
|
||||||
import org.springframework.util.Assert;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@link RequestCondition} implementation that represents a logical NOT (i.e. !).
|
|
||||||
*
|
|
||||||
* @author Arjen Poutsma
|
|
||||||
* @since 3.1
|
|
||||||
*/
|
|
||||||
class LogicalNegationRequestCondition extends AbstractRequestCondition {
|
|
||||||
|
|
||||||
private final RequestCondition requestCondition;
|
|
||||||
|
|
||||||
LogicalNegationRequestCondition(RequestCondition requestCondition) {
|
|
||||||
Assert.notNull(requestCondition, "'requestCondition' must not be null");
|
|
||||||
this.requestCondition = requestCondition;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected int getSpecificity() {
|
|
||||||
if (requestCondition instanceof AbstractRequestCondition) {
|
|
||||||
return ((AbstractRequestCondition) requestCondition).getSpecificity();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean match(HttpServletRequest request) {
|
|
||||||
return !requestCondition.match(request);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if (this == o) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (o != null && o instanceof LogicalNegationRequestCondition) {
|
|
||||||
LogicalNegationRequestCondition other = (LogicalNegationRequestCondition) o;
|
|
||||||
return this.requestCondition.equals(other.requestCondition);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return requestCondition.hashCode();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "!(" + requestCondition.toString() + ")";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,73 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2002-2011 the original author or authors.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.springframework.web.servlet.mvc.method.condition;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
|
|
||||||
import org.springframework.http.MediaType;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A RequestCondition that for headers that contain {@link org.springframework.http.MediaType MediaTypes}.
|
|
||||||
*/
|
|
||||||
class MediaTypeHeaderRequestCondition extends AbstractNameValueCondition<List<MediaType>> {
|
|
||||||
|
|
||||||
public MediaTypeHeaderRequestCondition(String expression) {
|
|
||||||
super(expression);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected List<MediaType> parseValue(String valueExpression) {
|
|
||||||
return Collections.unmodifiableList(MediaType.parseMediaTypes(valueExpression));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean matchName(HttpServletRequest request) {
|
|
||||||
return request.getHeader(name) != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean matchValue(HttpServletRequest request) {
|
|
||||||
List<MediaType> requestMediaTypes = MediaType.parseMediaTypes(request.getHeader(name));
|
|
||||||
|
|
||||||
for (MediaType mediaType : this.value) {
|
|
||||||
for (MediaType requestMediaType : requestMediaTypes) {
|
|
||||||
if (mediaType.includes(requestMediaType)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object obj) {
|
|
||||||
if (this == obj) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (obj != null && obj instanceof MediaTypeHeaderRequestCondition) {
|
|
||||||
MediaTypeHeaderRequestCondition other = (MediaTypeHeaderRequestCondition) obj;
|
|
||||||
return ((this.name.equalsIgnoreCase(other.name)) &&
|
|
||||||
(this.value != null ? this.value.equals(other.value) : other.value == null) &&
|
|
||||||
this.isNegated == other.isNegated);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,66 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2002-2011 the original author or authors.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.springframework.web.servlet.mvc.method.condition;
|
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
|
|
||||||
import org.springframework.web.util.WebUtils;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Request parameter name-value condition.
|
|
||||||
*
|
|
||||||
* @author Rossen Stoyanchev
|
|
||||||
* @author Arjen Poutsma
|
|
||||||
* @see org.springframework.web.bind.annotation.RequestMapping#params()
|
|
||||||
* @since 3.1
|
|
||||||
*/
|
|
||||||
class ParamRequestCondition extends AbstractNameValueCondition<String> {
|
|
||||||
|
|
||||||
ParamRequestCondition(String expression) {
|
|
||||||
super(expression);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected String parseValue(String valueExpression) {
|
|
||||||
return valueExpression;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean matchName(HttpServletRequest request) {
|
|
||||||
return WebUtils.hasSubmitParameter(request, name);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean matchValue(HttpServletRequest request) {
|
|
||||||
return value.equals(request.getParameter(name));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object obj) {
|
|
||||||
if (this == obj) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (obj != null && obj instanceof ParamRequestCondition) {
|
|
||||||
ParamRequestCondition other = (ParamRequestCondition) obj;
|
|
||||||
return ((this.name.equals(other.name)) &&
|
|
||||||
(this.value != null ? this.value.equals(other.value) : other.value == null) &&
|
|
||||||
this.isNegated == other.isNegated);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,126 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2002-2011 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.springframework.web.servlet.mvc.method.condition;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.LinkedHashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
|
import org.springframework.web.util.WebUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a collection of parameter request conditions, typically obtained from {@link
|
||||||
|
* org.springframework.web.bind.annotation.RequestMapping#params() @RequestMapping.params()}.
|
||||||
|
*
|
||||||
|
* @author Arjen Poutsma
|
||||||
|
* @see RequestConditionFactory#parseParams(String...)
|
||||||
|
* @since 3.1
|
||||||
|
*/
|
||||||
|
public class ParamsRequestCondition
|
||||||
|
extends LogicalConjunctionRequestCondition<ParamsRequestCondition.ParamRequestCondition>
|
||||||
|
implements Comparable<ParamsRequestCondition> {
|
||||||
|
|
||||||
|
private ParamsRequestCondition(Collection<ParamRequestCondition> conditions) {
|
||||||
|
super(conditions);
|
||||||
|
}
|
||||||
|
|
||||||
|
ParamsRequestCondition(String... params) {
|
||||||
|
this(parseConditions(Arrays.asList(params)));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Set<ParamRequestCondition> parseConditions(List<String> params) {
|
||||||
|
Set<ParamRequestCondition> conditions = new LinkedHashSet<ParamRequestCondition>(params.size());
|
||||||
|
for (String param : params) {
|
||||||
|
conditions.add(new ParamRequestCondition(param));
|
||||||
|
}
|
||||||
|
return conditions;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an empty set of parameter request conditions.
|
||||||
|
*/
|
||||||
|
public ParamsRequestCondition() {
|
||||||
|
this(Collections.<ParamRequestCondition>emptySet());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a new {@code RequestCondition} that contains all conditions of this key that match the request.
|
||||||
|
*
|
||||||
|
* @param request the request
|
||||||
|
* @return a new request condition that contains all matching attributes, or {@code null} if not all conditions match
|
||||||
|
*/
|
||||||
|
public ParamsRequestCondition getMatchingCondition(HttpServletRequest request) {
|
||||||
|
return match(request) ? this : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Combines this collection of request condition with another by combining all parameter request conditions into a
|
||||||
|
* logical AND.
|
||||||
|
*
|
||||||
|
* @param other the condition to combine with
|
||||||
|
*/
|
||||||
|
public ParamsRequestCondition combine(ParamsRequestCondition other) {
|
||||||
|
Set<ParamRequestCondition> conditions = new LinkedHashSet<ParamRequestCondition>(getConditions());
|
||||||
|
conditions.addAll(other.getConditions());
|
||||||
|
return new ParamsRequestCondition(conditions);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int compareTo(ParamsRequestCondition other) {
|
||||||
|
return other.getConditions().size() - this.getConditions().size();
|
||||||
|
}
|
||||||
|
|
||||||
|
static class ParamRequestCondition extends AbstractNameValueCondition<String> {
|
||||||
|
|
||||||
|
ParamRequestCondition(String expression) {
|
||||||
|
super(expression);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String parseValue(String valueExpression) {
|
||||||
|
return valueExpression;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean matchName(HttpServletRequest request) {
|
||||||
|
return WebUtils.hasSubmitParameter(request, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean matchValue(HttpServletRequest request) {
|
||||||
|
return value.equals(request.getParameter(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (obj != null && obj instanceof ParamRequestCondition) {
|
||||||
|
ParamRequestCondition other = (ParamRequestCondition) obj;
|
||||||
|
return ((this.name.equals(other.name)) &&
|
||||||
|
(this.value != null ? this.value.equals(other.value) : other.value == null) &&
|
||||||
|
this.isNegated == other.isNegated);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -29,7 +29,7 @@ import javax.servlet.http.HttpServletRequest;
|
||||||
* @see RequestConditionFactory
|
* @see RequestConditionFactory
|
||||||
* @since 3.1
|
* @since 3.1
|
||||||
*/
|
*/
|
||||||
public interface RequestCondition extends Comparable<RequestCondition> {
|
public interface RequestCondition {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates whether this condition matches against the given servlet request.
|
* Indicates whether this condition matches against the given servlet request.
|
||||||
|
|
|
||||||
|
|
@ -16,11 +16,11 @@
|
||||||
|
|
||||||
package org.springframework.web.servlet.mvc.method.condition;
|
package org.springframework.web.servlet.mvc.method.condition;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.LinkedHashSet;
|
||||||
|
import java.util.Set;
|
||||||
import org.springframework.util.Assert;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstract base class for {@link RequestCondition} implementations that wrap other request conditions.
|
* Abstract base class for {@link RequestCondition} implementations that wrap other request conditions.
|
||||||
|
|
@ -28,25 +28,16 @@ import org.springframework.util.Assert;
|
||||||
* @author Arjen Poutsma
|
* @author Arjen Poutsma
|
||||||
* @since 3.1
|
* @since 3.1
|
||||||
*/
|
*/
|
||||||
abstract class RequestConditionComposite extends AbstractRequestCondition {
|
abstract class RequestConditionComposite<T extends RequestCondition> implements RequestCondition {
|
||||||
|
|
||||||
protected final List<RequestCondition> conditions;
|
private final Set<T> conditions;
|
||||||
|
|
||||||
protected RequestConditionComposite(List<RequestCondition> conditions) {
|
protected RequestConditionComposite(Collection<T> conditions) {
|
||||||
Assert.notEmpty(conditions, "'conditions' must not be empty");
|
this.conditions = Collections.unmodifiableSet(new LinkedHashSet<T>(conditions));
|
||||||
this.conditions = Collections.unmodifiableList(conditions);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
protected Set<T> getConditions() {
|
||||||
public int getSpecificity() {
|
return conditions;
|
||||||
int weight = 0;
|
|
||||||
for (RequestCondition condition : conditions) {
|
|
||||||
if (condition instanceof AbstractRequestCondition) {
|
|
||||||
AbstractRequestCondition abstractRequestCondition = (AbstractRequestCondition) condition;
|
|
||||||
weight += abstractRequestCondition.getSpecificity();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return weight;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -70,7 +61,7 @@ abstract class RequestConditionComposite extends AbstractRequestCondition {
|
||||||
public String toString() {
|
public String toString() {
|
||||||
StringBuilder builder = new StringBuilder("[");
|
StringBuilder builder = new StringBuilder("[");
|
||||||
String infix = getToStringInfix();
|
String infix = getToStringInfix();
|
||||||
for (Iterator<RequestCondition> iterator = conditions.iterator(); iterator.hasNext();) {
|
for (Iterator<T> iterator = conditions.iterator(); iterator.hasNext();) {
|
||||||
RequestCondition condition = iterator.next();
|
RequestCondition condition = iterator.next();
|
||||||
builder.append(condition.toString());
|
builder.append(condition.toString());
|
||||||
if (iterator.hasNext()) {
|
if (iterator.hasNext()) {
|
||||||
|
|
|
||||||
|
|
@ -17,13 +17,12 @@
|
||||||
package org.springframework.web.servlet.mvc.method.condition;
|
package org.springframework.web.servlet.mvc.method.condition;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
import java.util.LinkedHashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.springframework.util.ObjectUtils;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.util.StringUtils;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Factory for {@link RequestCondition} objects.
|
* Factory for {@link RequestCondition} objects.
|
||||||
|
|
@ -34,132 +33,9 @@ import org.springframework.util.StringUtils;
|
||||||
*/
|
*/
|
||||||
public abstract class RequestConditionFactory {
|
public abstract class RequestConditionFactory {
|
||||||
|
|
||||||
private static final RequestCondition TRUE_CONDITION = new AbstractRequestCondition() {
|
private static final String CONTENT_TYPE_HEADER = "Content-Type";
|
||||||
public boolean match(HttpServletRequest request) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
private static final String ACCEPT_HEADER = "Accept";
|
||||||
public int getSpecificity() {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "TRUE";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private static final RequestCondition FALSE_CONDITION = new AbstractRequestCondition() {
|
|
||||||
public boolean match(HttpServletRequest request) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getSpecificity() {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "FALSE";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a condition that always returns {@code true} for {@link RequestCondition#match(HttpServletRequest)}.
|
|
||||||
*
|
|
||||||
* @return a condition that returns {@code true}
|
|
||||||
*/
|
|
||||||
public static RequestCondition trueCondition() {
|
|
||||||
return TRUE_CONDITION;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a condition that always returns {@code false} for {@link RequestCondition#match(HttpServletRequest)}.
|
|
||||||
*
|
|
||||||
* @return a condition that returns {@code false}
|
|
||||||
*/
|
|
||||||
public static RequestCondition falseCondition() {
|
|
||||||
return FALSE_CONDITION;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static RequestCondition mostSpecific(RequestCondition... conditions) {
|
|
||||||
if (ObjectUtils.isEmpty(conditions)) {
|
|
||||||
return trueCondition();
|
|
||||||
}
|
|
||||||
RequestCondition[] copy = new RequestCondition[conditions.length];
|
|
||||||
System.arraycopy(conditions, 0, copy, 0, conditions.length);
|
|
||||||
Arrays.sort(copy);
|
|
||||||
return copy[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Wraps the given condition in a logical NOT, i.e. the returned condition will return {@code true} for {@link
|
|
||||||
* RequestCondition#match(HttpServletRequest)} if the given condition return {@code false}, and vice-versa.
|
|
||||||
*
|
|
||||||
* @return a condition that represents a logical NOT
|
|
||||||
*/
|
|
||||||
public static RequestCondition not(RequestCondition condition) {
|
|
||||||
if (condition == TRUE_CONDITION) {
|
|
||||||
return falseCondition();
|
|
||||||
}
|
|
||||||
else if (condition == FALSE_CONDITION) {
|
|
||||||
return trueCondition();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return new LogicalNegationRequestCondition(condition);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Combines the given conditions into a logical AND, i.e. the returned condition will return {@code true} for {@link
|
|
||||||
* RequestCondition#match(HttpServletRequest)} if all of the given conditions do so.
|
|
||||||
*
|
|
||||||
* @param conditions the conditions
|
|
||||||
* @return a condition that represents a logical AND
|
|
||||||
*/
|
|
||||||
public static RequestCondition and(RequestCondition... conditions) {
|
|
||||||
List<RequestCondition> filteredConditions = new ArrayList<RequestCondition>(Arrays.asList(conditions));
|
|
||||||
for (Iterator<RequestCondition> iterator = filteredConditions.iterator(); iterator.hasNext();) {
|
|
||||||
RequestCondition condition = iterator.next();
|
|
||||||
if (condition == TRUE_CONDITION) {
|
|
||||||
iterator.remove();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (filteredConditions.isEmpty()) {
|
|
||||||
return trueCondition();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return new LogicalConjunctionRequestCondition(filteredConditions);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Combines the given conditions into a logical OR, i.e. the returned condition will return {@code true} for {@link
|
|
||||||
* RequestCondition#match(HttpServletRequest)} if any of the given conditions do so.
|
|
||||||
*
|
|
||||||
* @param conditions the conditions
|
|
||||||
* @return a condition that represents a logical OR
|
|
||||||
*/
|
|
||||||
public static RequestCondition or(RequestCondition... conditions) {
|
|
||||||
List<RequestCondition> filteredConditions = new ArrayList<RequestCondition>(Arrays.asList(conditions));
|
|
||||||
for (Iterator<RequestCondition> iterator = filteredConditions.iterator(); iterator.hasNext();) {
|
|
||||||
RequestCondition condition = iterator.next();
|
|
||||||
if (condition == TRUE_CONDITION) {
|
|
||||||
return trueCondition();
|
|
||||||
}
|
|
||||||
else if (condition == FALSE_CONDITION) {
|
|
||||||
iterator.remove();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (filteredConditions.isEmpty()) {
|
|
||||||
return trueCondition();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return new LogicalDisjunctionRequestCondition(filteredConditions);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses the given parameters, and returns them as a single request conditions.
|
* Parses the given parameters, and returns them as a single request conditions.
|
||||||
|
|
@ -168,15 +44,8 @@ public abstract class RequestConditionFactory {
|
||||||
* @return the request condition
|
* @return the request condition
|
||||||
* @see org.springframework.web.bind.annotation.RequestMapping#params()
|
* @see org.springframework.web.bind.annotation.RequestMapping#params()
|
||||||
*/
|
*/
|
||||||
public static RequestCondition parseParams(String... params) {
|
public static ParamsRequestCondition parseParams(String... params) {
|
||||||
if (ObjectUtils.isEmpty(params)) {
|
return new ParamsRequestCondition(params);
|
||||||
return trueCondition();
|
|
||||||
}
|
|
||||||
RequestCondition[] result = new RequestCondition[params.length];
|
|
||||||
for (int i = 0; i < params.length; i++) {
|
|
||||||
result[i] = new ParamRequestCondition(params[i]);
|
|
||||||
}
|
|
||||||
return and(result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -186,29 +55,22 @@ public abstract class RequestConditionFactory {
|
||||||
* @return the request condition
|
* @return the request condition
|
||||||
* @see org.springframework.web.bind.annotation.RequestMapping#headers()
|
* @see org.springframework.web.bind.annotation.RequestMapping#headers()
|
||||||
*/
|
*/
|
||||||
public static RequestCondition parseHeaders(String... headers) {
|
public static HeadersRequestCondition parseHeaders(String... headers) {
|
||||||
if (ObjectUtils.isEmpty(headers)) {
|
HeadersRequestCondition headersCondition = new HeadersRequestCondition(headers);
|
||||||
return trueCondition();
|
|
||||||
}
|
|
||||||
RequestCondition[] result = new RequestCondition[headers.length];
|
|
||||||
for (int i = 0; i < headers.length; i++) {
|
|
||||||
HeaderRequestCondition header = new HeaderRequestCondition(headers[i]);
|
|
||||||
if ("Content-Type".equalsIgnoreCase(header.name) && StringUtils.hasLength(header.value)) {
|
|
||||||
RequestCondition consumesCondition = new ConsumesRequestCondition(header.value);
|
|
||||||
result[i] = header.isNegated ? not(consumesCondition) : consumesCondition;
|
|
||||||
}
|
|
||||||
else if (isMediaTypeHeader(header.name)) {
|
|
||||||
result[i] = new MediaTypeHeaderRequestCondition(headers[i]);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
result[i] = header;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return and(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean isMediaTypeHeader(String name) {
|
// filter out Accept and Content-Type headers, they are dealt with by produces and consumes respectively
|
||||||
return "Accept".equalsIgnoreCase(name) || "Content-Type".equalsIgnoreCase(name);
|
Set<HeadersRequestCondition.HeaderRequestCondition> filteredConditions =
|
||||||
|
new LinkedHashSet<HeadersRequestCondition.HeaderRequestCondition>(headersCondition.getConditions());
|
||||||
|
|
||||||
|
for (Iterator<HeadersRequestCondition.HeaderRequestCondition> iterator = filteredConditions.iterator();
|
||||||
|
iterator.hasNext();) {
|
||||||
|
HeadersRequestCondition.HeaderRequestCondition headerCondition = iterator.next();
|
||||||
|
if (ACCEPT_HEADER.equalsIgnoreCase(headerCondition.name) ||
|
||||||
|
CONTENT_TYPE_HEADER.equalsIgnoreCase(headerCondition.name)) {
|
||||||
|
iterator.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new HeadersRequestCondition(filteredConditions);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -218,15 +80,39 @@ public abstract class RequestConditionFactory {
|
||||||
* @return the request condition
|
* @return the request condition
|
||||||
* @see org.springframework.web.bind.annotation.RequestMapping#consumes()
|
* @see org.springframework.web.bind.annotation.RequestMapping#consumes()
|
||||||
*/
|
*/
|
||||||
public static RequestCondition parseConsumes(String... consumes) {
|
public static ConsumesRequestCondition parseConsumes(String... consumes) {
|
||||||
if (ObjectUtils.isEmpty(consumes)) {
|
return new ConsumesRequestCondition(consumes);
|
||||||
return trueCondition();
|
|
||||||
}
|
}
|
||||||
RequestCondition[] result = new RequestCondition[consumes.length];
|
|
||||||
for (int i = 0; i < consumes.length; i++) {
|
public static ConsumesRequestCondition parseConsumes(String[] consumes, String[] headers) {
|
||||||
result[i] = new ConsumesRequestCondition(consumes[i]);
|
|
||||||
|
List<ConsumesRequestCondition.ConsumeRequestCondition> allConditions = parseContentTypeHeaders(headers);
|
||||||
|
|
||||||
|
// ignore the default consumes() value if any content-type headers have been set
|
||||||
|
boolean headersHasContentType = !allConditions.isEmpty();
|
||||||
|
boolean consumesHasDefaultValue = consumes.length == 1 && consumes[0].equals("*/*");
|
||||||
|
if (!headersHasContentType || !consumesHasDefaultValue) {
|
||||||
|
for (String consume : consumes) {
|
||||||
|
allConditions.add(new ConsumesRequestCondition.ConsumeRequestCondition(consume));
|
||||||
}
|
}
|
||||||
return or(result);
|
}
|
||||||
|
return new ConsumesRequestCondition(allConditions);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<ConsumesRequestCondition.ConsumeRequestCondition> parseContentTypeHeaders(String[] headers) {
|
||||||
|
List<ConsumesRequestCondition.ConsumeRequestCondition> allConditions =
|
||||||
|
new ArrayList<ConsumesRequestCondition.ConsumeRequestCondition>();
|
||||||
|
HeadersRequestCondition headersCondition = new HeadersRequestCondition(headers);
|
||||||
|
for (HeadersRequestCondition.HeaderRequestCondition headerCondition : headersCondition.getConditions()) {
|
||||||
|
if (CONTENT_TYPE_HEADER.equalsIgnoreCase(headerCondition.name)) {
|
||||||
|
List<MediaType> mediaTypes = MediaType.parseMediaTypes(headerCondition.value);
|
||||||
|
for (MediaType mediaType : mediaTypes) {
|
||||||
|
allConditions.add(
|
||||||
|
new ConsumesRequestCondition.ConsumeRequestCondition(mediaType, headerCondition.isNegated));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return allConditions;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,192 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2002-2011 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.springframework.web.servlet.mvc.method.condition;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import org.springframework.mock.web.MockHttpServletRequest;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Arjen Poutsma
|
||||||
|
*/
|
||||||
|
public class ConsumesRequestConditionTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void consumesMatch() {
|
||||||
|
RequestCondition condition = new ConsumesRequestCondition("text/plain");
|
||||||
|
|
||||||
|
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||||
|
request.setContentType("text/plain");
|
||||||
|
|
||||||
|
assertTrue(condition.match(request));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void negatedConsumesMatch() {
|
||||||
|
RequestCondition condition = new ConsumesRequestCondition("!text/plain");
|
||||||
|
|
||||||
|
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||||
|
request.setContentType("text/plain");
|
||||||
|
|
||||||
|
assertFalse(condition.match(request));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void consumesWildcardMatch() {
|
||||||
|
RequestCondition condition = new ConsumesRequestCondition("text/*");
|
||||||
|
|
||||||
|
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||||
|
request.setContentType("text/plain");
|
||||||
|
|
||||||
|
assertTrue(condition.match(request));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void consumesMultipleMatch() {
|
||||||
|
RequestCondition condition = new ConsumesRequestCondition("text/plain", "application/xml");
|
||||||
|
|
||||||
|
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||||
|
request.setContentType("text/plain");
|
||||||
|
|
||||||
|
assertTrue(condition.match(request));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void consumesSingleNoMatch() {
|
||||||
|
RequestCondition condition = new ConsumesRequestCondition("text/plain");
|
||||||
|
|
||||||
|
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||||
|
request.setContentType("application/xml");
|
||||||
|
|
||||||
|
assertFalse(condition.match(request));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void compareToSingle() {
|
||||||
|
ConsumesRequestCondition condition1 = new ConsumesRequestCondition("text/plain");
|
||||||
|
ConsumesRequestCondition condition2 = new ConsumesRequestCondition("text/*");
|
||||||
|
|
||||||
|
int result = condition1.compareTo(condition2);
|
||||||
|
assertTrue("Invalid comparison result: " + result, result < 0);
|
||||||
|
|
||||||
|
result = condition2.compareTo(condition1);
|
||||||
|
assertTrue("Invalid comparison result: " + result, result > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void compareToMultiple() {
|
||||||
|
ConsumesRequestCondition condition1 = new ConsumesRequestCondition("*/*", "text/plain");
|
||||||
|
ConsumesRequestCondition condition2 = new ConsumesRequestCondition("text/*", "text/plain;q=0.7");
|
||||||
|
|
||||||
|
int result = condition1.compareTo(condition2);
|
||||||
|
assertTrue("Invalid comparison result: " + result, result < 0);
|
||||||
|
|
||||||
|
result = condition2.compareTo(condition1);
|
||||||
|
assertTrue("Invalid comparison result: " + result, result > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void combine() {
|
||||||
|
ConsumesRequestCondition condition1 = new ConsumesRequestCondition("text/plain");
|
||||||
|
ConsumesRequestCondition condition2 = new ConsumesRequestCondition("application/xml");
|
||||||
|
|
||||||
|
ConsumesRequestCondition result = condition1.combine(condition2);
|
||||||
|
assertEquals(condition2, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void combineWithDefault() {
|
||||||
|
ConsumesRequestCondition condition1 = new ConsumesRequestCondition("text/plain");
|
||||||
|
ConsumesRequestCondition condition2 = new ConsumesRequestCondition("*/*");
|
||||||
|
|
||||||
|
ConsumesRequestCondition result = condition1.combine(condition2);
|
||||||
|
assertEquals(condition1, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void parseConsumesAndHeaders() {
|
||||||
|
String[] consumes = new String[] {"text/plain"};
|
||||||
|
String[] headers = new String[]{"foo=bar", "content-type=application/xml,application/pdf"};
|
||||||
|
ConsumesRequestCondition condition = RequestConditionFactory.parseConsumes(consumes, headers);
|
||||||
|
|
||||||
|
assertConditions(condition, "text/plain", "application/xml", "application/pdf");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void parseConsumesDefault() {
|
||||||
|
String[] consumes = new String[] {"*/*"};
|
||||||
|
String[] headers = new String[0];
|
||||||
|
ConsumesRequestCondition condition = RequestConditionFactory.parseConsumes(consumes, headers);
|
||||||
|
|
||||||
|
assertConditions(condition, "*/*");
|
||||||
|
}
|
||||||
|
@Test
|
||||||
|
public void parseConsumesDefaultAndHeaders() {
|
||||||
|
String[] consumes = new String[] {"*/*"};
|
||||||
|
String[] headers = new String[]{"foo=bar", "content-type=text/plain"};
|
||||||
|
ConsumesRequestCondition condition = RequestConditionFactory.parseConsumes(consumes, headers);
|
||||||
|
|
||||||
|
assertConditions(condition, "text/plain");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getMatchingCondition() {
|
||||||
|
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||||
|
request.setContentType("text/plain");
|
||||||
|
|
||||||
|
ConsumesRequestCondition condition = new ConsumesRequestCondition("text/plain", "application/xml");
|
||||||
|
|
||||||
|
ConsumesRequestCondition result = condition.getMatchingCondition(request);
|
||||||
|
assertConditions(result, "text/plain");
|
||||||
|
|
||||||
|
condition = new ConsumesRequestCondition("application/xml");
|
||||||
|
|
||||||
|
result = condition.getMatchingCondition(request);
|
||||||
|
assertNull(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertConditions(ConsumesRequestCondition condition, String... expected) {
|
||||||
|
Set<ConsumesRequestCondition.ConsumeRequestCondition> conditions = condition.getConditions();
|
||||||
|
assertEquals("Invalid amount of conditions", conditions.size(), expected.length);
|
||||||
|
for (String s : expected) {
|
||||||
|
boolean found = false;
|
||||||
|
for (ConsumesRequestCondition.ConsumeRequestCondition requestCondition : conditions) {
|
||||||
|
String conditionMediaType = requestCondition.getMediaType().toString();
|
||||||
|
if (conditionMediaType.equals(s)) {
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found) {
|
||||||
|
fail("Condition [" + s + "] not found");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,150 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2002-2011 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.springframework.web.servlet.mvc.method.condition;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import org.springframework.mock.web.MockHttpServletRequest;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Arjen Poutsma
|
||||||
|
*/
|
||||||
|
public class HeadersRequestConditionTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void headerEquals() {
|
||||||
|
assertEquals(new HeadersRequestCondition("foo"), new HeadersRequestCondition("foo"));
|
||||||
|
assertEquals(new HeadersRequestCondition("foo"), new HeadersRequestCondition("FOO"));
|
||||||
|
assertFalse(new HeadersRequestCondition("foo").equals(new HeadersRequestCondition("bar")));
|
||||||
|
assertEquals(new HeadersRequestCondition("foo=bar"), new HeadersRequestCondition("foo=bar"));
|
||||||
|
assertEquals(new HeadersRequestCondition("foo=bar"), new HeadersRequestCondition("FOO=bar"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void headerPresent() {
|
||||||
|
RequestCondition condition = new HeadersRequestCondition("accept");
|
||||||
|
|
||||||
|
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||||
|
request.addHeader("Accept", "");
|
||||||
|
|
||||||
|
assertTrue(condition.match(request));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void headerPresentNoMatch() {
|
||||||
|
RequestCondition condition = new HeadersRequestCondition("foo");
|
||||||
|
|
||||||
|
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||||
|
request.addHeader("bar", "");
|
||||||
|
|
||||||
|
assertFalse(condition.match(request));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void headerNotPresent() {
|
||||||
|
RequestCondition condition = new HeadersRequestCondition("!accept");
|
||||||
|
|
||||||
|
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||||
|
|
||||||
|
assertTrue(condition.match(request));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void headerValueMatch() {
|
||||||
|
RequestCondition condition = new HeadersRequestCondition("foo=bar");
|
||||||
|
|
||||||
|
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||||
|
request.addHeader("foo", "bar");
|
||||||
|
|
||||||
|
assertTrue(condition.match(request));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void headerValueNoMatch() {
|
||||||
|
RequestCondition condition = new HeadersRequestCondition("foo=bar");
|
||||||
|
|
||||||
|
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||||
|
request.addHeader("foo", "bazz");
|
||||||
|
|
||||||
|
assertFalse(condition.match(request));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void headerCaseSensitiveValueMatch() {
|
||||||
|
RequestCondition condition = new HeadersRequestCondition("foo=Bar");
|
||||||
|
|
||||||
|
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||||
|
request.addHeader("foo", "bar");
|
||||||
|
|
||||||
|
assertFalse(condition.match(request));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void headerValueMatchNegated() {
|
||||||
|
RequestCondition condition = new HeadersRequestCondition("foo!=bar");
|
||||||
|
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||||
|
request.addHeader("foo", "baz");
|
||||||
|
|
||||||
|
assertTrue(condition.match(request));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void compareTo() {
|
||||||
|
HeadersRequestCondition condition1 = new HeadersRequestCondition("foo", "bar", "baz");
|
||||||
|
HeadersRequestCondition condition2 = new HeadersRequestCondition("foo", "bar");
|
||||||
|
|
||||||
|
int result = condition1.compareTo(condition2);
|
||||||
|
assertTrue("Invalid comparison result: " + result, result < 0);
|
||||||
|
|
||||||
|
result = condition2.compareTo(condition1);
|
||||||
|
assertTrue("Invalid comparison result: " + result, result > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void combine() {
|
||||||
|
HeadersRequestCondition condition1 = new HeadersRequestCondition("foo=bar");
|
||||||
|
HeadersRequestCondition condition2 = new HeadersRequestCondition("foo=baz");
|
||||||
|
|
||||||
|
HeadersRequestCondition result = condition1.combine(condition2);
|
||||||
|
Set<HeadersRequestCondition.HeaderRequestCondition> conditions = result.getConditions();
|
||||||
|
assertEquals(2, conditions.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getMatchingCondition() {
|
||||||
|
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||||
|
request.addHeader("foo", "bar");
|
||||||
|
|
||||||
|
HeadersRequestCondition condition = new HeadersRequestCondition("foo");
|
||||||
|
|
||||||
|
HeadersRequestCondition result = condition.getMatchingCondition(request);
|
||||||
|
assertEquals(condition, result);
|
||||||
|
|
||||||
|
condition = new HeadersRequestCondition("bar");
|
||||||
|
|
||||||
|
result = condition.getMatchingCondition(request);
|
||||||
|
assertNull(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,129 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2002-2011 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.springframework.web.servlet.mvc.method.condition;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import org.springframework.mock.web.MockHttpServletRequest;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Arjen Poutsma
|
||||||
|
*/
|
||||||
|
public class ParamsRequestConditionTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void paramEquals() {
|
||||||
|
assertEquals(new ParamsRequestCondition("foo"), new ParamsRequestCondition("foo"));
|
||||||
|
assertFalse(new ParamsRequestCondition("foo").equals(new ParamsRequestCondition("bar")));
|
||||||
|
assertFalse(new ParamsRequestCondition("foo").equals(new ParamsRequestCondition("FOO")));
|
||||||
|
assertEquals(new ParamsRequestCondition("foo=bar"), new ParamsRequestCondition("foo=bar"));
|
||||||
|
assertFalse(
|
||||||
|
new ParamsRequestCondition("foo=bar").equals(new ParamsRequestCondition("FOO=bar")));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void paramPresent() {
|
||||||
|
RequestCondition condition = new ParamsRequestCondition("foo");
|
||||||
|
|
||||||
|
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||||
|
request.addParameter("foo", "");
|
||||||
|
|
||||||
|
assertTrue(condition.match(request));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void paramPresentNoMatch() {
|
||||||
|
RequestCondition condition = new ParamsRequestCondition("foo");
|
||||||
|
|
||||||
|
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||||
|
request.addHeader("bar", "");
|
||||||
|
|
||||||
|
assertFalse(condition.match(request));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void paramNotPresent() {
|
||||||
|
RequestCondition condition = new ParamsRequestCondition("!foo");
|
||||||
|
|
||||||
|
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||||
|
|
||||||
|
assertTrue(condition.match(request));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void paramValueMatch() {
|
||||||
|
RequestCondition condition = new ParamsRequestCondition("foo=bar");
|
||||||
|
|
||||||
|
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||||
|
request.addParameter("foo", "bar");
|
||||||
|
|
||||||
|
assertTrue(condition.match(request));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void paramValueNoMatch() {
|
||||||
|
RequestCondition condition = new ParamsRequestCondition("foo=bar");
|
||||||
|
|
||||||
|
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||||
|
request.addParameter("foo", "bazz");
|
||||||
|
|
||||||
|
assertFalse(condition.match(request));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void compareTo() {
|
||||||
|
ParamsRequestCondition condition1 = new ParamsRequestCondition("foo", "bar", "baz");
|
||||||
|
ParamsRequestCondition condition2 = new ParamsRequestCondition("foo", "bar");
|
||||||
|
|
||||||
|
int result = condition1.compareTo(condition2);
|
||||||
|
assertTrue("Invalid comparison result: " + result, result < 0);
|
||||||
|
|
||||||
|
result = condition2.compareTo(condition1);
|
||||||
|
assertTrue("Invalid comparison result: " + result, result > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void combine() {
|
||||||
|
ParamsRequestCondition condition1 = new ParamsRequestCondition("foo=bar");
|
||||||
|
ParamsRequestCondition condition2 = new ParamsRequestCondition("foo=baz");
|
||||||
|
|
||||||
|
ParamsRequestCondition result = condition1.combine(condition2);
|
||||||
|
Set<ParamsRequestCondition.ParamRequestCondition> conditions = result.getConditions();
|
||||||
|
assertEquals(2, conditions.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getMatchingCondition() {
|
||||||
|
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||||
|
request.addParameter("foo", "bar");
|
||||||
|
|
||||||
|
ParamsRequestCondition condition = new ParamsRequestCondition("foo");
|
||||||
|
|
||||||
|
ParamsRequestCondition result = condition.getMatchingCondition(request);
|
||||||
|
assertEquals(condition, result);
|
||||||
|
|
||||||
|
condition = new ParamsRequestCondition("bar");
|
||||||
|
|
||||||
|
result = condition.getMatchingCondition(request);
|
||||||
|
assertNull(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -1,212 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2002-2011 the original author or authors.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.springframework.web.servlet.mvc.method.condition;
|
|
||||||
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import org.springframework.mock.web.MockHttpServletRequest;
|
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Arjen Poutsma
|
|
||||||
*/
|
|
||||||
public class RequestConditionFactoryTests {
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void andMatch() {
|
|
||||||
RequestCondition condition1 = RequestConditionFactory.trueCondition();
|
|
||||||
RequestCondition condition2 = RequestConditionFactory.trueCondition();
|
|
||||||
RequestCondition and = RequestConditionFactory.and(condition1, condition2);
|
|
||||||
assertTrue(and.match(new MockHttpServletRequest()));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void andNoMatch() {
|
|
||||||
RequestCondition condition1 = RequestConditionFactory.trueCondition();
|
|
||||||
RequestCondition condition2 = RequestConditionFactory.falseCondition();
|
|
||||||
RequestCondition and = RequestConditionFactory.and(condition1, condition2);
|
|
||||||
assertFalse(and.match(new MockHttpServletRequest()));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void orMatch() {
|
|
||||||
RequestCondition condition1 = RequestConditionFactory.trueCondition();
|
|
||||||
RequestCondition condition2 = RequestConditionFactory.falseCondition();
|
|
||||||
RequestCondition and = RequestConditionFactory.or(condition1, condition2);
|
|
||||||
assertTrue(and.match(new MockHttpServletRequest()));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void orNoMatch() {
|
|
||||||
RequestCondition condition1 = RequestConditionFactory.falseCondition();
|
|
||||||
RequestCondition condition2 = RequestConditionFactory.falseCondition();
|
|
||||||
RequestCondition and = RequestConditionFactory.and(condition1, condition2);
|
|
||||||
assertFalse(and.match(new MockHttpServletRequest()));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void paramEquals() {
|
|
||||||
assertEquals(RequestConditionFactory.parseParams("foo"), RequestConditionFactory.parseParams("foo"));
|
|
||||||
assertFalse(RequestConditionFactory.parseParams("foo").equals(RequestConditionFactory.parseParams("bar")));
|
|
||||||
assertFalse(RequestConditionFactory.parseParams("foo").equals(RequestConditionFactory.parseParams("FOO")));
|
|
||||||
assertEquals(RequestConditionFactory.parseParams("foo=bar"), RequestConditionFactory.parseParams("foo=bar"));
|
|
||||||
assertFalse(
|
|
||||||
RequestConditionFactory.parseParams("foo=bar").equals(RequestConditionFactory.parseParams("FOO=bar")));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void headerEquals() {
|
|
||||||
assertEquals(RequestConditionFactory.parseHeaders("foo"), RequestConditionFactory.parseHeaders("foo"));
|
|
||||||
assertEquals(RequestConditionFactory.parseHeaders("foo"), RequestConditionFactory.parseHeaders("FOO"));
|
|
||||||
assertFalse(RequestConditionFactory.parseHeaders("foo").equals(RequestConditionFactory.parseHeaders("bar")));
|
|
||||||
assertEquals(RequestConditionFactory.parseHeaders("foo=bar"), RequestConditionFactory.parseHeaders("foo=bar"));
|
|
||||||
assertEquals(RequestConditionFactory.parseHeaders("foo=bar"), RequestConditionFactory.parseHeaders("FOO=bar"));
|
|
||||||
assertEquals(RequestConditionFactory.parseHeaders("content-type=text/xml"),
|
|
||||||
RequestConditionFactory.parseHeaders("Content-Type=TEXT/XML"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void headerPresent() {
|
|
||||||
RequestCondition condition = RequestConditionFactory.parseHeaders("accept");
|
|
||||||
|
|
||||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
|
||||||
request.addHeader("Accept", "");
|
|
||||||
|
|
||||||
assertTrue(condition.match(request));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void headerPresentNoMatch() {
|
|
||||||
RequestCondition condition = RequestConditionFactory.parseHeaders("foo");
|
|
||||||
|
|
||||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
|
||||||
request.addHeader("bar", "");
|
|
||||||
|
|
||||||
assertFalse(condition.match(request));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void headerNotPresent() {
|
|
||||||
RequestCondition condition = RequestConditionFactory.parseHeaders("!accept");
|
|
||||||
|
|
||||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
|
||||||
|
|
||||||
assertTrue(condition.match(request));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void headerValueMatch() {
|
|
||||||
RequestCondition condition = RequestConditionFactory.parseHeaders("foo=bar");
|
|
||||||
|
|
||||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
|
||||||
request.addHeader("foo", "bar");
|
|
||||||
|
|
||||||
assertTrue(condition.match(request));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void headerValueNoMatch() {
|
|
||||||
RequestCondition condition = RequestConditionFactory.parseHeaders("foo=bar");
|
|
||||||
|
|
||||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
|
||||||
request.addHeader("foo", "bazz");
|
|
||||||
|
|
||||||
assertFalse(condition.match(request));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void headerCaseSensitiveValueMatch() {
|
|
||||||
RequestCondition condition = RequestConditionFactory.parseHeaders("foo=Bar");
|
|
||||||
|
|
||||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
|
||||||
request.addHeader("foo", "bar");
|
|
||||||
|
|
||||||
assertFalse(condition.match(request));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void headerValueMatchNegated() {
|
|
||||||
RequestCondition condition = RequestConditionFactory.parseHeaders("foo!=bar");
|
|
||||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
|
||||||
request.addHeader("foo", "baz");
|
|
||||||
|
|
||||||
assertTrue(condition.match(request));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void mediaTypeHeaderValueMatch() {
|
|
||||||
RequestCondition condition = RequestConditionFactory.parseHeaders("accept=text/html");
|
|
||||||
|
|
||||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
|
||||||
request.addHeader("Accept", "text/html");
|
|
||||||
|
|
||||||
assertTrue(condition.match(request));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void mediaTypeHeaderValueMatchNegated() {
|
|
||||||
RequestCondition condition = RequestConditionFactory.parseHeaders("accept!=text/html");
|
|
||||||
|
|
||||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
|
||||||
request.addHeader("Accept", "application/html");
|
|
||||||
|
|
||||||
assertTrue(condition.match(request));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void consumesMatch() {
|
|
||||||
RequestCondition condition = RequestConditionFactory.parseConsumes("text/plain");
|
|
||||||
|
|
||||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
|
||||||
request.setContentType("text/plain");
|
|
||||||
|
|
||||||
assertTrue(condition.match(request));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void consumesWildcardMatch() {
|
|
||||||
RequestCondition condition = RequestConditionFactory.parseConsumes("text/*");
|
|
||||||
|
|
||||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
|
||||||
request.setContentType("text/plain");
|
|
||||||
|
|
||||||
assertTrue(condition.match(request));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void consumesMultipleMatch() {
|
|
||||||
RequestCondition condition = RequestConditionFactory.parseConsumes("text/plain", "application/xml");
|
|
||||||
|
|
||||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
|
||||||
request.setContentType("text/plain");
|
|
||||||
|
|
||||||
assertTrue(condition.match(request));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void consumesSingleNoMatch() {
|
|
||||||
RequestCondition condition = RequestConditionFactory.parseConsumes("text/plain");
|
|
||||||
|
|
||||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
|
||||||
request.setContentType("application/xml");
|
|
||||||
|
|
||||||
assertFalse(condition.match(request));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -153,7 +153,7 @@ import java.lang.annotation.Target;
|
||||||
* converters}.
|
* converters}.
|
||||||
* <li>A {@link org.springframework.http.HttpEntity HttpEntity<?>} or
|
* <li>A {@link org.springframework.http.HttpEntity HttpEntity<?>} or
|
||||||
* {@link org.springframework.http.ResponseEntity ResponseEntity<?>} object
|
* {@link org.springframework.http.ResponseEntity ResponseEntity<?>} object
|
||||||
* to access to the Servlet reponse HTTP headers and contents. The entity body will
|
* to access to the Servlet response HTTP headers and contents. The entity body will
|
||||||
* be converted to the response stream using
|
* be converted to the response stream using
|
||||||
* {@linkplain org.springframework.http.converter.HttpMessageConverter message
|
* {@linkplain org.springframework.http.converter.HttpMessageConverter message
|
||||||
* converters}.
|
* converters}.
|
||||||
|
|
@ -297,4 +297,18 @@ public @interface RequestMapping {
|
||||||
*/
|
*/
|
||||||
String[] headers() default {};
|
String[] headers() default {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The consumable media types of the mapped request, narrowing the primary mapping.
|
||||||
|
* <p>The format is a sequence of media types ("text/plain", "application/*),
|
||||||
|
* with a request only mapped if the {@code Content-Type} matches one of these media types.
|
||||||
|
* Expressions can be negated by using the "!" operator, as in "!text/plain", which matches
|
||||||
|
* all requests with a {@code Content-Type} other than "text/plain".
|
||||||
|
* <p><b>Supported at the type level as well as at the method level!</b>
|
||||||
|
* When used at the type level, all method-level mappings override
|
||||||
|
* this consumes restriction.
|
||||||
|
* @see org.springframework.http.MediaType
|
||||||
|
* @see javax.servlet.http.HttpServletRequest#getContentType()
|
||||||
|
*/
|
||||||
|
String[] consumes() default "*/*";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue