SPR-7354 - Added equivalent of JAX-RS @Consumes to Spring MVC
This commit is contained in:
parent
381af43f91
commit
bf6693dbc5
|
|
@ -1,285 +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.annotation;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.LinkedHashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
|
|
||||||
import org.springframework.http.MediaType;
|
|
||||||
import org.springframework.web.util.WebUtils;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Factory for request condition objects.
|
|
||||||
*
|
|
||||||
* @author Arjen Poutsma
|
|
||||||
* @author Rossen Stoyanchev
|
|
||||||
*/
|
|
||||||
public abstract class RequestConditionFactory {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parses the given parameters, and returns them as a set of request conditions.
|
|
||||||
*
|
|
||||||
* @param params the parameters
|
|
||||||
* @return the request conditions
|
|
||||||
* @see org.springframework.web.bind.annotation.RequestMapping#params()
|
|
||||||
*/
|
|
||||||
public static Set<RequestCondition> parseParams(String... params) {
|
|
||||||
if (params == null) {
|
|
||||||
return Collections.emptySet();
|
|
||||||
}
|
|
||||||
Set<RequestCondition> result = new LinkedHashSet<RequestCondition>(params.length);
|
|
||||||
for (String expression : params) {
|
|
||||||
result.add(new ParamNameValueCondition(expression));
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parses the given headers, and returns them as a set of request conditions.
|
|
||||||
*
|
|
||||||
* @param headers the headers
|
|
||||||
* @return the request conditions
|
|
||||||
* @see org.springframework.web.bind.annotation.RequestMapping#headers()
|
|
||||||
*/
|
|
||||||
public static Set<RequestCondition> parseHeaders(String... headers) {
|
|
||||||
if (headers == null) {
|
|
||||||
return Collections.emptySet();
|
|
||||||
}
|
|
||||||
Set<RequestCondition> result = new LinkedHashSet<RequestCondition>(headers.length);
|
|
||||||
for (String expression : headers) {
|
|
||||||
HeaderNameValueCondition header = new HeaderNameValueCondition(expression);
|
|
||||||
if (isMediaTypeHeader(header.name)) {
|
|
||||||
result.add(new MediaTypeHeaderNameValueCondition(expression));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
result.add(header);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean isMediaTypeHeader(String name) {
|
|
||||||
return "Accept".equalsIgnoreCase(name) || "Content-Type".equalsIgnoreCase(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A condition that supports simple "name=value" style expressions as documented in
|
|
||||||
* <code>@RequestMapping.params()</code> and <code>@RequestMapping.headers()</code>.
|
|
||||||
*/
|
|
||||||
private static abstract class AbstractNameValueCondition<T> implements RequestCondition {
|
|
||||||
|
|
||||||
protected final String name;
|
|
||||||
|
|
||||||
protected final T value;
|
|
||||||
|
|
||||||
protected final boolean isNegated;
|
|
||||||
|
|
||||||
protected AbstractNameValueCondition(String expression) {
|
|
||||||
int separator = expression.indexOf('=');
|
|
||||||
if (separator == -1) {
|
|
||||||
this.isNegated = expression.startsWith("!");
|
|
||||||
this.name = isNegated ? expression.substring(1) : expression;
|
|
||||||
this.value = null;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.isNegated = (separator > 0) && (expression.charAt(separator - 1) == '!');
|
|
||||||
this.name = isNegated ? expression.substring(0, separator - 1) : expression.substring(0, separator);
|
|
||||||
this.value = parseValue(expression.substring(separator + 1));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract T parseValue(String valueExpression);
|
|
||||||
|
|
||||||
public final boolean match(HttpServletRequest request) {
|
|
||||||
boolean isMatch;
|
|
||||||
if (this.value != null) {
|
|
||||||
isMatch = matchValue(request);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
isMatch = matchName(request);
|
|
||||||
}
|
|
||||||
return isNegated ? !isMatch : isMatch;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract boolean matchName(HttpServletRequest request);
|
|
||||||
|
|
||||||
protected abstract boolean matchValue(HttpServletRequest request);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
StringBuilder builder = new StringBuilder();
|
|
||||||
if (value != null) {
|
|
||||||
builder.append(name);
|
|
||||||
if (isNegated) {
|
|
||||||
builder.append('!');
|
|
||||||
}
|
|
||||||
builder.append('=');
|
|
||||||
builder.append(value);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (isNegated) {
|
|
||||||
builder.append('!');
|
|
||||||
}
|
|
||||||
builder.append(name);
|
|
||||||
}
|
|
||||||
return builder.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
int result = name.hashCode();
|
|
||||||
result = 31 * result + (value != null ? value.hashCode() : 0);
|
|
||||||
result = 31 * result + (isNegated ? 1 : 0);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Request parameter name-value condition.
|
|
||||||
*/
|
|
||||||
private static class ParamNameValueCondition extends AbstractNameValueCondition<String> {
|
|
||||||
|
|
||||||
private ParamNameValueCondition(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 ParamNameValueCondition) {
|
|
||||||
ParamNameValueCondition other = (ParamNameValueCondition) obj;
|
|
||||||
return ((this.name.equals(other.name)) &&
|
|
||||||
(this.value != null ? this.value.equals(other.value) : other.value == null) &&
|
|
||||||
this.isNegated == other.isNegated);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Request header name-value condition.
|
|
||||||
*/
|
|
||||||
static class HeaderNameValueCondition extends AbstractNameValueCondition<String> {
|
|
||||||
|
|
||||||
public HeaderNameValueCondition(String expression) {
|
|
||||||
super(expression);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected String parseValue(String valueExpression) {
|
|
||||||
return valueExpression;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean matchName(HttpServletRequest request) {
|
|
||||||
return request.getHeader(name) != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
final 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 HeaderNameValueCondition) {
|
|
||||||
HeaderNameValueCondition other = (HeaderNameValueCondition) obj;
|
|
||||||
return ((this.name.equalsIgnoreCase(other.name)) &&
|
|
||||||
(this.value != null ? this.value.equals(other.value) : other.value == null) &&
|
|
||||||
this.isNegated == other.isNegated);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A RequestCondition that for headers that contain {@link org.springframework.http.MediaType MediaTypes}.
|
|
||||||
*/
|
|
||||||
private static class MediaTypeHeaderNameValueCondition extends AbstractNameValueCondition<List<MediaType>> {
|
|
||||||
|
|
||||||
public MediaTypeHeaderNameValueCondition(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 MediaTypeHeaderNameValueCondition) {
|
|
||||||
MediaTypeHeaderNameValueCondition other = (MediaTypeHeaderNameValueCondition) obj;
|
|
||||||
return ((this.name.equalsIgnoreCase(other.name)) &&
|
|
||||||
(this.value != null ? this.value.equals(other.value) : other.value == null) &&
|
|
||||||
this.isNegated == other.isNegated);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -23,12 +23,13 @@ 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.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
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.RequestConditionFactory;
|
||||||
import org.springframework.web.util.UrlPathHelper;
|
import org.springframework.web.util.UrlPathHelper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -43,12 +44,18 @@ public final class RequestKey {
|
||||||
|
|
||||||
private final Set<RequestMethod> methods;
|
private final Set<RequestMethod> methods;
|
||||||
|
|
||||||
private final Set<RequestCondition> paramConditions;
|
private final RequestCondition paramsCondition;
|
||||||
|
|
||||||
private final Set<RequestCondition> headerConditions;
|
private final RequestCondition headersCondition;
|
||||||
|
|
||||||
|
private final RequestCondition consumesCondition;
|
||||||
|
|
||||||
private int hash;
|
private int hash;
|
||||||
|
|
||||||
|
RequestKey(Collection<String> patterns, Collection<RequestMethod> methods) {
|
||||||
|
this(patterns, methods, null, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new {@code RequestKey} instance with the given parameters.
|
* Creates a new {@code RequestKey} instance with the given parameters.
|
||||||
*
|
*
|
||||||
|
|
@ -56,12 +63,14 @@ public final class RequestKey {
|
||||||
*/
|
*/
|
||||||
RequestKey(Collection<String> patterns,
|
RequestKey(Collection<String> patterns,
|
||||||
Collection<RequestMethod> methods,
|
Collection<RequestMethod> methods,
|
||||||
Collection<RequestCondition> paramConditions,
|
RequestCondition paramsCondition,
|
||||||
Collection<RequestCondition> headerConditions) {
|
RequestCondition headersCondition,
|
||||||
|
RequestCondition consumesCondition) {
|
||||||
this.patterns = asUnmodifiableSet(prependLeadingSlash(patterns));
|
this.patterns = asUnmodifiableSet(prependLeadingSlash(patterns));
|
||||||
this.methods = asUnmodifiableSet(methods);
|
this.methods = asUnmodifiableSet(methods);
|
||||||
this.paramConditions = asUnmodifiableSet(paramConditions);
|
this.paramsCondition = paramsCondition != null ? paramsCondition : RequestConditionFactory.trueCondition();
|
||||||
this.headerConditions = asUnmodifiableSet(headerConditions);
|
this.headersCondition = headersCondition != null ? headersCondition : RequestConditionFactory.trueCondition();
|
||||||
|
this.consumesCondition = consumesCondition != null ? consumesCondition : RequestConditionFactory.trueCondition();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Set<String> prependLeadingSlash(Collection<String> patterns) {
|
private static Set<String> prependLeadingSlash(Collection<String> patterns) {
|
||||||
|
|
@ -95,7 +104,9 @@ public final class RequestKey {
|
||||||
public static RequestKey createFromRequestMapping(RequestMapping annotation) {
|
public static RequestKey createFromRequestMapping(RequestMapping annotation) {
|
||||||
return new RequestKey(Arrays.asList(annotation.value()), Arrays.asList(annotation.method()),
|
return new RequestKey(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(annotation.consumes())
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -109,7 +120,7 @@ public final class RequestKey {
|
||||||
public static RequestKey createFromServletRequest(HttpServletRequest request, UrlPathHelper urlPathHelper) {
|
public static RequestKey createFromServletRequest(HttpServletRequest request, UrlPathHelper urlPathHelper) {
|
||||||
String lookupPath = urlPathHelper.getLookupPathForRequest(request);
|
String lookupPath = urlPathHelper.getLookupPathForRequest(request);
|
||||||
RequestMethod method = RequestMethod.valueOf(request.getMethod());
|
RequestMethod method = RequestMethod.valueOf(request.getMethod());
|
||||||
return new RequestKey(Arrays.asList(lookupPath), Arrays.asList(method), null, null);
|
return new RequestKey(Collections.singleton(lookupPath), Collections.singleton(method));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -129,32 +140,32 @@ public final class RequestKey {
|
||||||
/**
|
/**
|
||||||
* Returns the request parameters of this request key.
|
* Returns the request parameters of this request key.
|
||||||
*/
|
*/
|
||||||
public Set<RequestCondition> getParams() {
|
public RequestCondition getParams() {
|
||||||
return paramConditions;
|
return paramsCondition;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the request headers of this request key.
|
* Returns the request headers of this request key.
|
||||||
*/
|
*/
|
||||||
public Set<RequestCondition> getHeaders() {
|
public RequestCondition getHeaders() {
|
||||||
return headerConditions;
|
return headersCondition;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new {@code RequestKey} by combining it with another. The typical use case for this is combining type
|
* Combines this {@code RequestKey} with another. The typical use case for this is combining type
|
||||||
* and method-level {@link RequestMapping @RequestMapping} annotations.
|
* and method-level {@link RequestMapping @RequestMapping} annotations.
|
||||||
*
|
*
|
||||||
* @param methodKey the method-level RequestKey
|
* @param other the method-level RequestKey
|
||||||
* @param pathMatcher to {@linkplain PathMatcher#combine(String, String) combine} the patterns
|
* @param pathMatcher to {@linkplain PathMatcher#combine(String, String) combine} the patterns
|
||||||
* @return the combined request key
|
* @return the combined request key
|
||||||
*/
|
*/
|
||||||
public RequestKey combine(RequestKey methodKey, PathMatcher pathMatcher) {
|
public RequestKey combine(RequestKey other, PathMatcher pathMatcher) {
|
||||||
Set<String> patterns = combinePatterns(this.patterns, methodKey.patterns, pathMatcher);
|
Set<String> patterns = combinePatterns(this.patterns, other.patterns, pathMatcher);
|
||||||
Set<RequestMethod> methods = union(this.methods, methodKey.methods);
|
Set<RequestMethod> methods = union(this.methods, other.methods);
|
||||||
Set<RequestCondition> params = union(this.paramConditions, methodKey.paramConditions);
|
RequestCondition params = RequestConditionFactory.and(this.paramsCondition, other.paramsCondition);
|
||||||
Set<RequestCondition> headers = union(this.headerConditions, methodKey.headerConditions);
|
RequestCondition headers = RequestConditionFactory.and(this.headersCondition, other.headersCondition);
|
||||||
|
|
||||||
return new RequestKey(patterns, methods, params, headers);
|
return new RequestKey(patterns, methods, params, headers, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Set<String> combinePatterns(Collection<String> typePatterns,
|
private static Set<String> combinePatterns(Collection<String> typePatterns,
|
||||||
|
|
@ -205,7 +216,7 @@ public final class RequestKey {
|
||||||
List<String> matchingPatterns = getMatchingPatterns(request, pathMatcher, urlPathHelper);
|
List<String> matchingPatterns = getMatchingPatterns(request, pathMatcher, urlPathHelper);
|
||||||
if (!matchingPatterns.isEmpty()) {
|
if (!matchingPatterns.isEmpty()) {
|
||||||
Set<RequestMethod> matchingMethods = getMatchingMethods(request);
|
Set<RequestMethod> matchingMethods = getMatchingMethods(request);
|
||||||
return new RequestKey(matchingPatterns, matchingMethods, this.paramConditions, this.headerConditions);
|
return new RequestKey(matchingPatterns, matchingMethods, this.paramsCondition, this.headersCondition, null);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return null;
|
return null;
|
||||||
|
|
@ -245,11 +256,11 @@ public final class RequestKey {
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean checkParams(HttpServletRequest request) {
|
private boolean checkParams(HttpServletRequest request) {
|
||||||
return checkConditions(paramConditions, request);
|
return paramsCondition.match(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean checkHeaders(HttpServletRequest request) {
|
private boolean checkHeaders(HttpServletRequest request) {
|
||||||
return checkConditions(headerConditions, request);
|
return headersCondition.match(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getMatchingPattern(String pattern, String lookupPath, PathMatcher pathMatcher) {
|
private String getMatchingPattern(String pattern, String lookupPath, PathMatcher pathMatcher) {
|
||||||
|
|
@ -284,8 +295,8 @@ public final class RequestKey {
|
||||||
if (obj != null && obj instanceof RequestKey) {
|
if (obj != null && obj instanceof RequestKey) {
|
||||||
RequestKey other = (RequestKey) obj;
|
RequestKey other = (RequestKey) obj;
|
||||||
return (this.patterns.equals(other.patterns) && this.methods.equals(other.methods) &&
|
return (this.patterns.equals(other.patterns) && this.methods.equals(other.methods) &&
|
||||||
this.paramConditions.equals(other.paramConditions) &&
|
this.paramsCondition.equals(other.paramsCondition) &&
|
||||||
this.headerConditions.equals(other.headerConditions));
|
this.headersCondition.equals(other.headersCondition));
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -296,8 +307,8 @@ public final class RequestKey {
|
||||||
if (result == 0) {
|
if (result == 0) {
|
||||||
result = patterns.hashCode();
|
result = patterns.hashCode();
|
||||||
result = 31 * result + methods.hashCode();
|
result = 31 * result + methods.hashCode();
|
||||||
result = 31 * result + paramConditions.hashCode();
|
result = 31 * result + paramsCondition.hashCode();
|
||||||
result = 31 * result + headerConditions.hashCode();
|
result = 31 * result + headersCondition.hashCode();
|
||||||
hash = result;
|
hash = result;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
|
@ -311,14 +322,9 @@ public final class RequestKey {
|
||||||
builder.append(',');
|
builder.append(',');
|
||||||
builder.append(methods);
|
builder.append(methods);
|
||||||
}
|
}
|
||||||
if (!headerConditions.isEmpty()) {
|
builder.append(",params=").append(paramsCondition.toString());
|
||||||
builder.append(',');
|
builder.append(",headers=").append(headersCondition.toString());
|
||||||
builder.append(headerConditions);
|
builder.append(",consumes=").append(consumesCondition.toString());
|
||||||
}
|
|
||||||
if (!paramConditions.isEmpty()) {
|
|
||||||
builder.append(',');
|
|
||||||
builder.append(paramConditions);
|
|
||||||
}
|
|
||||||
builder.append('}');
|
builder.append('}');
|
||||||
return builder.toString();
|
return builder.toString();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,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;
|
||||||
|
|
@ -253,11 +252,11 @@ public class RequestMappingHandlerMethodMapping extends AbstractHandlerMethodMap
|
||||||
if (result != 0) {
|
if (result != 0) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
result = otherKey.getParams().size() - key.getParams().size();
|
result = otherKey.getParams().weight() - key.getParams().weight();
|
||||||
if (result != 0) {
|
if (result != 0) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
result = otherKey.getHeaders().size() - key.getHeaders().size();
|
result = otherKey.getHeaders().weight() - key.getHeaders().weight();
|
||||||
if (result != 0) {
|
if (result != 0) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,100 @@
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A condition that supports simple "name=value" style expressions as documented in {@link
|
||||||
|
* org.springframework.web.bind.annotation.RequestMapping#params()} and {@link org.springframework.web.bind.annotation.RequestMapping#headers()}.
|
||||||
|
*
|
||||||
|
* @author Rossen Stoyanchev
|
||||||
|
* @author Arjen Poutsma
|
||||||
|
* @since 3.1
|
||||||
|
*/
|
||||||
|
abstract class AbstractNameValueCondition<T> implements RequestCondition {
|
||||||
|
|
||||||
|
protected final String name;
|
||||||
|
|
||||||
|
protected final T value;
|
||||||
|
|
||||||
|
protected final boolean isNegated;
|
||||||
|
|
||||||
|
AbstractNameValueCondition(String expression) {
|
||||||
|
int separator = expression.indexOf('=');
|
||||||
|
if (separator == -1) {
|
||||||
|
this.isNegated = expression.startsWith("!");
|
||||||
|
this.name = isNegated ? expression.substring(1) : expression;
|
||||||
|
this.value = null;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.isNegated = (separator > 0) && (expression.charAt(separator - 1) == '!');
|
||||||
|
this.name = isNegated ? expression.substring(0, separator - 1) : expression.substring(0, separator);
|
||||||
|
this.value = parseValue(expression.substring(separator + 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract T parseValue(String valueExpression);
|
||||||
|
|
||||||
|
public final boolean match(HttpServletRequest request) {
|
||||||
|
boolean isMatch;
|
||||||
|
if (this.value != null) {
|
||||||
|
isMatch = matchValue(request);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
isMatch = matchName(request);
|
||||||
|
}
|
||||||
|
return isNegated ? !isMatch : isMatch;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract boolean matchName(HttpServletRequest request);
|
||||||
|
|
||||||
|
protected abstract boolean matchValue(HttpServletRequest request);
|
||||||
|
|
||||||
|
public int weight() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int result = name.hashCode();
|
||||||
|
result = 31 * result + (value != null ? value.hashCode() : 0);
|
||||||
|
result = 31 * result + (isNegated ? 1 : 0);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
if (value != null) {
|
||||||
|
builder.append(name);
|
||||||
|
if (isNegated) {
|
||||||
|
builder.append('!');
|
||||||
|
}
|
||||||
|
builder.append('=');
|
||||||
|
builder.append(value);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (isNegated) {
|
||||||
|
builder.append('!');
|
||||||
|
}
|
||||||
|
builder.append(name);
|
||||||
|
}
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,47 @@
|
||||||
|
/*
|
||||||
|
* 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.http.MediaType;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Arjen Poutsma
|
||||||
|
*/
|
||||||
|
class ConsumesRequestCondition implements RequestCondition {
|
||||||
|
|
||||||
|
private final MediaType mediaType;
|
||||||
|
|
||||||
|
ConsumesRequestCondition(String mediaType) {
|
||||||
|
this.mediaType = MediaType.parseMediaType(mediaType);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean match(HttpServletRequest request) {
|
||||||
|
String contentTypeString = request.getContentType();
|
||||||
|
if (StringUtils.hasLength(contentTypeString)) {
|
||||||
|
MediaType contentType = MediaType.parseMediaType(contentTypeString);
|
||||||
|
return this.mediaType.includes(contentType);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int weight() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,64 @@
|
||||||
|
/*
|
||||||
|
* 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,48 @@
|
||||||
|
/*
|
||||||
|
* 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.List;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link RequestCondition} implementation that represents a logical AND (i.e. &&).
|
||||||
|
*
|
||||||
|
* @author Arjen Poutsma
|
||||||
|
* @since 3.1
|
||||||
|
*/
|
||||||
|
class LogicalConjunctionRequestCondition extends RequestConditionComposite {
|
||||||
|
|
||||||
|
LogicalConjunctionRequestCondition(List<RequestCondition> conditions) {
|
||||||
|
super(conditions);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean match(HttpServletRequest request) {
|
||||||
|
for (RequestCondition condition : conditions) {
|
||||||
|
if (!condition.match(request)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getToStringInfix() {
|
||||||
|
return " && ";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -14,16 +14,35 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.web.servlet.mvc.method.annotation;
|
package org.springframework.web.servlet.mvc.method.condition;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A condition that can be matched to a ServletRequest.
|
* {@link RequestCondition} implementation that represents a logical OR (i.e. ||).
|
||||||
*
|
*
|
||||||
* @author Rossen Stoyanchev
|
* @author Arjen Poutsma
|
||||||
|
* @since 3.1
|
||||||
*/
|
*/
|
||||||
interface RequestCondition {
|
class LogicalDisjunctionRequestCondition extends RequestConditionComposite {
|
||||||
|
|
||||||
|
LogicalDisjunctionRequestCondition(List<RequestCondition> conditions) {
|
||||||
|
super(conditions);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean match(HttpServletRequest request) {
|
||||||
|
for (RequestCondition condition : conditions) {
|
||||||
|
if (condition.match(request)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getToStringInfix() {
|
||||||
|
return " || ";
|
||||||
|
}
|
||||||
|
|
||||||
boolean match(HttpServletRequest request);
|
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,73 @@
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,66 @@
|
||||||
|
/*
|
||||||
|
* 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,49 @@
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines the contract for conditions that must be met before an incoming request matches a {@link
|
||||||
|
* org.springframework.web.servlet.mvc.method.annotation.RequestKey RequestKey}.
|
||||||
|
*
|
||||||
|
* <p>Implementations of this interface are created by the {@link RequestConditionFactory}.
|
||||||
|
*
|
||||||
|
* @author Rossen Stoyanchev
|
||||||
|
* @author Arjen Poutsma
|
||||||
|
* @see RequestConditionFactory
|
||||||
|
* @since 3.1
|
||||||
|
*/
|
||||||
|
public interface RequestCondition {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates whether this condition matches against the given servlet request.
|
||||||
|
*
|
||||||
|
* @param request the request
|
||||||
|
* @return {@code true} if this condition matches the request; {@code false} otherwise
|
||||||
|
*/
|
||||||
|
boolean match(HttpServletRequest request);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates the relative weight of this condition. More important conditions have a higher weight than ones that are
|
||||||
|
* less so.
|
||||||
|
*
|
||||||
|
* @return the weight of this condition
|
||||||
|
*/
|
||||||
|
int weight();
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,77 @@
|
||||||
|
/*
|
||||||
|
* 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.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstract base class for {@link RequestCondition} implementations that wrap other request conditions.
|
||||||
|
*
|
||||||
|
* @author Arjen Poutsma
|
||||||
|
* @since 3.1
|
||||||
|
*/
|
||||||
|
abstract class RequestConditionComposite implements RequestCondition {
|
||||||
|
|
||||||
|
protected final List<RequestCondition> conditions;
|
||||||
|
|
||||||
|
public RequestConditionComposite(List<RequestCondition> conditions) {
|
||||||
|
this.conditions = conditions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int weight() {
|
||||||
|
int size = 0;
|
||||||
|
for (RequestCondition condition : conditions) {
|
||||||
|
size += condition.weight();
|
||||||
|
}
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (o != null && getClass().equals(o.getClass())) {
|
||||||
|
RequestConditionComposite other = (RequestConditionComposite) o;
|
||||||
|
return this.conditions.equals(other.conditions);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return conditions.hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
StringBuilder builder = new StringBuilder("[");
|
||||||
|
String infix = getToStringInfix();
|
||||||
|
for (Iterator<RequestCondition> iterator = conditions.iterator(); iterator.hasNext();) {
|
||||||
|
RequestCondition condition = iterator.next();
|
||||||
|
builder.append(condition.toString());
|
||||||
|
if (iterator.hasNext()) {
|
||||||
|
builder.append(infix);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
builder.append("]");
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract String getToStringInfix();
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,175 @@
|
||||||
|
/*
|
||||||
|
* 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.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
|
import org.springframework.util.ObjectUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Factory for {@link RequestCondition} objects.
|
||||||
|
*
|
||||||
|
* @author Arjen Poutsma
|
||||||
|
* @author Rossen Stoyanchev
|
||||||
|
* @since 3.1
|
||||||
|
*/
|
||||||
|
public abstract class RequestConditionFactory {
|
||||||
|
|
||||||
|
private static final RequestCondition TRUE_CONDITION = new RequestCondition() {
|
||||||
|
public boolean match(HttpServletRequest request) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int weight() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "TRUE";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private static final RequestCondition FALSE_CONDITION = new RequestCondition() {
|
||||||
|
public boolean match(HttpServletRequest request) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int weight() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "FALSE";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public static RequestCondition trueCondition() {
|
||||||
|
return TRUE_CONDITION;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static RequestCondition falseCondition() {
|
||||||
|
return FALSE_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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new LogicalDisjunctionRequestCondition(filteredConditions);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses the given parameters, and returns them as a single request conditions.
|
||||||
|
*
|
||||||
|
* @param params the parameters
|
||||||
|
* @return the request condition
|
||||||
|
* @see org.springframework.web.bind.annotation.RequestMapping#params()
|
||||||
|
*/
|
||||||
|
public static RequestCondition parseParams(String... params) {
|
||||||
|
if (ObjectUtils.isEmpty(params)) {
|
||||||
|
return TRUE_CONDITION;
|
||||||
|
}
|
||||||
|
RequestCondition[] result = new RequestCondition[params.length];
|
||||||
|
for (int i = 0; i < params.length; i++) {
|
||||||
|
result[i] = new ParamRequestCondition(params[i]);
|
||||||
|
}
|
||||||
|
return and(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses the given headers, and returns them as a single request condition.
|
||||||
|
*
|
||||||
|
* @param headers the headers
|
||||||
|
* @return the request condition
|
||||||
|
* @see org.springframework.web.bind.annotation.RequestMapping#headers()
|
||||||
|
*/
|
||||||
|
public static RequestCondition parseHeaders(String... headers) {
|
||||||
|
if (ObjectUtils.isEmpty(headers)) {
|
||||||
|
return TRUE_CONDITION;
|
||||||
|
}
|
||||||
|
RequestCondition[] result = new RequestCondition[headers.length];
|
||||||
|
for (int i = 0; i < headers.length; i++) {
|
||||||
|
HeaderRequestCondition header = new HeaderRequestCondition(headers[i]);
|
||||||
|
if (isMediaTypeHeader(header.name)) {
|
||||||
|
result[i] = new MediaTypeHeaderRequestCondition(headers[i]);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
result[i] = header;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return and(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isMediaTypeHeader(String name) {
|
||||||
|
return "Accept".equalsIgnoreCase(name) || "Content-Type".equalsIgnoreCase(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static RequestCondition parseConsumes(String... consumes) {
|
||||||
|
if (ObjectUtils.isEmpty(consumes)) {
|
||||||
|
return TRUE_CONDITION;
|
||||||
|
}
|
||||||
|
RequestCondition[] result = new RequestCondition[consumes.length];
|
||||||
|
for (int i = 0; i < consumes.length; i++) {
|
||||||
|
result[i] = new ConsumesRequestCondition(consumes[i]);
|
||||||
|
}
|
||||||
|
return or(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Conditions
|
||||||
|
//
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -1,155 +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.annotation;
|
|
||||||
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import org.springframework.mock.web.MockHttpServletRequest;
|
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.RequestCondition;
|
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.RequestConditionFactory;
|
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Arjen Poutsma
|
|
||||||
*/
|
|
||||||
public class RequestConditionFactoryTests {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void paramEquals() {
|
|
||||||
assertEquals(getSingleParamCondition("foo"), getSingleParamCondition("foo"));
|
|
||||||
assertFalse(getSingleParamCondition("foo").equals(getSingleParamCondition("bar")));
|
|
||||||
assertFalse(getSingleParamCondition("foo").equals(getSingleParamCondition("FOO")));
|
|
||||||
assertEquals(getSingleParamCondition("foo=bar"), getSingleParamCondition("foo=bar"));
|
|
||||||
assertFalse(getSingleParamCondition("foo=bar").equals(getSingleParamCondition("FOO=bar")));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void headerEquals() {
|
|
||||||
assertEquals(getSingleHeaderCondition("foo"), getSingleHeaderCondition("foo"));
|
|
||||||
assertEquals(getSingleHeaderCondition("foo"), getSingleHeaderCondition("FOO"));
|
|
||||||
assertFalse(getSingleHeaderCondition("foo").equals(getSingleHeaderCondition("bar")));
|
|
||||||
assertEquals(getSingleHeaderCondition("foo=bar"), getSingleHeaderCondition("foo=bar"));
|
|
||||||
assertEquals(getSingleHeaderCondition("foo=bar"), getSingleHeaderCondition("FOO=bar"));
|
|
||||||
assertEquals(getSingleHeaderCondition("content-type=text/xml"),
|
|
||||||
getSingleHeaderCondition("Content-Type=TEXT/XML"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void headerPresent() {
|
|
||||||
RequestCondition condition = getSingleHeaderCondition("accept");
|
|
||||||
|
|
||||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
|
||||||
request.addHeader("Accept", "");
|
|
||||||
|
|
||||||
assertTrue(condition.match(request));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void headerPresentNoMatch() {
|
|
||||||
RequestCondition condition = getSingleHeaderCondition("foo");
|
|
||||||
|
|
||||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
|
||||||
request.addHeader("bar", "");
|
|
||||||
|
|
||||||
assertFalse(condition.match(request));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void headerNotPresent() {
|
|
||||||
RequestCondition condition = getSingleHeaderCondition("!accept");
|
|
||||||
|
|
||||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
|
||||||
|
|
||||||
assertTrue(condition.match(request));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void headerValueMatch() {
|
|
||||||
RequestCondition condition = getSingleHeaderCondition("foo=bar");
|
|
||||||
|
|
||||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
|
||||||
request.addHeader("foo", "bar");
|
|
||||||
|
|
||||||
assertTrue(condition.match(request));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void headerValueNoMatch() {
|
|
||||||
RequestCondition condition = getSingleHeaderCondition("foo=bar");
|
|
||||||
|
|
||||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
|
||||||
request.addHeader("foo", "bazz");
|
|
||||||
|
|
||||||
assertFalse(condition.match(request));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void headerCaseSensitiveValueMatch() {
|
|
||||||
RequestCondition condition = getSingleHeaderCondition("foo=Bar");
|
|
||||||
|
|
||||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
|
||||||
request.addHeader("foo", "bar");
|
|
||||||
|
|
||||||
assertFalse(condition.match(request));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void headerValueMatchNegated() {
|
|
||||||
RequestCondition condition = getSingleHeaderCondition("foo!=bar");
|
|
||||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
|
||||||
request.addHeader("foo", "baz");
|
|
||||||
|
|
||||||
assertTrue(condition.match(request));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void mediaTypeHeaderValueMatch() {
|
|
||||||
RequestCondition condition = getSingleHeaderCondition("accept=text/html");
|
|
||||||
|
|
||||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
|
||||||
request.addHeader("Accept", "text/html");
|
|
||||||
|
|
||||||
assertTrue(condition.match(request));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void mediaTypeHeaderValueMatchNegated() {
|
|
||||||
RequestCondition condition = getSingleHeaderCondition("accept!=text/html");
|
|
||||||
|
|
||||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
|
||||||
request.addHeader("Accept", "application/html");
|
|
||||||
|
|
||||||
assertTrue(condition.match(request));
|
|
||||||
}
|
|
||||||
|
|
||||||
private RequestCondition getSingleHeaderCondition(String expression) {
|
|
||||||
Set<RequestCondition> conditions = RequestConditionFactory.parseHeaders(expression);
|
|
||||||
assertEquals(1, conditions.size());
|
|
||||||
return conditions.iterator().next();
|
|
||||||
}
|
|
||||||
|
|
||||||
private RequestCondition getSingleParamCondition(String expression) {
|
|
||||||
Set<RequestCondition> conditions = RequestConditionFactory.parseParams(expression);
|
|
||||||
assertEquals(1, conditions.size());
|
|
||||||
return conditions.iterator().next();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -16,11 +16,6 @@
|
||||||
|
|
||||||
package org.springframework.web.servlet.mvc.method.annotation;
|
package org.springframework.web.servlet.mvc.method.annotation;
|
||||||
|
|
||||||
import static java.util.Arrays.asList;
|
|
||||||
import static org.junit.Assert.assertEquals;
|
|
||||||
import static org.junit.Assert.assertSame;
|
|
||||||
import static org.junit.Assert.assertTrue;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
@ -28,11 +23,13 @@ import java.util.List;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Ignore;
|
import org.junit.Ignore;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import org.springframework.mock.web.MockHttpServletRequest;
|
import org.springframework.mock.web.MockHttpServletRequest;
|
||||||
import org.springframework.web.bind.annotation.RequestMethod;
|
import org.springframework.web.bind.annotation.RequestMethod;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.RequestConditionFactory;
|
import org.springframework.web.servlet.mvc.method.condition.RequestConditionFactory;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.RequestKey;
|
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMethodMapping;
|
import static java.util.Arrays.*;
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Arjen Poutsma
|
* @author Arjen Poutsma
|
||||||
|
|
@ -54,8 +51,8 @@ public class RequestKeyComparatorTests {
|
||||||
public void moreSpecificPatternWins() {
|
public void moreSpecificPatternWins() {
|
||||||
request.setRequestURI("/foo");
|
request.setRequestURI("/foo");
|
||||||
Comparator<RequestKey> comparator = handlerMapping.getKeyComparator(request);
|
Comparator<RequestKey> comparator = handlerMapping.getKeyComparator(request);
|
||||||
RequestKey key1 = new RequestKey(asList("/fo*"), null, null, null);
|
RequestKey key1 = new RequestKey(asList("/fo*"), null);
|
||||||
RequestKey key2 = new RequestKey(asList("/foo"), null, null, null);
|
RequestKey key2 = new RequestKey(asList("/foo"), null);
|
||||||
|
|
||||||
assertEquals(1, comparator.compare(key1, key2));
|
assertEquals(1, comparator.compare(key1, key2));
|
||||||
}
|
}
|
||||||
|
|
@ -64,8 +61,8 @@ public class RequestKeyComparatorTests {
|
||||||
public void equalPatterns() {
|
public void equalPatterns() {
|
||||||
request.setRequestURI("/foo");
|
request.setRequestURI("/foo");
|
||||||
Comparator<RequestKey> comparator = handlerMapping.getKeyComparator(request);
|
Comparator<RequestKey> comparator = handlerMapping.getKeyComparator(request);
|
||||||
RequestKey key1 = new RequestKey(asList("/foo*"), null, null, null);
|
RequestKey key1 = new RequestKey(asList("/foo*"), null);
|
||||||
RequestKey key2 = new RequestKey(asList("/foo*"), null, null, null);
|
RequestKey key2 = new RequestKey(asList("/foo*"), null);
|
||||||
|
|
||||||
assertEquals(0, comparator.compare(key1, key2));
|
assertEquals(0, comparator.compare(key1, key2));
|
||||||
}
|
}
|
||||||
|
|
@ -73,8 +70,8 @@ public class RequestKeyComparatorTests {
|
||||||
@Test
|
@Test
|
||||||
public void greaterNumberOfMatchingPatternsWins() throws Exception {
|
public void greaterNumberOfMatchingPatternsWins() throws Exception {
|
||||||
request.setRequestURI("/foo.html");
|
request.setRequestURI("/foo.html");
|
||||||
RequestKey key1 = new RequestKey(asList("/foo", "*.jpeg"), null, null, null);
|
RequestKey key1 = new RequestKey(asList("/foo", "*.jpeg"), null);
|
||||||
RequestKey key2 = new RequestKey(asList("/foo", "*.html"), null, null, null);
|
RequestKey key2 = new RequestKey(asList("/foo", "*.html"), null);
|
||||||
RequestKey match1 = handlerMapping.getMatchingKey(key1, request);
|
RequestKey match1 = handlerMapping.getMatchingKey(key1, request);
|
||||||
RequestKey match2 = handlerMapping.getMatchingKey(key2, request);
|
RequestKey match2 = handlerMapping.getMatchingKey(key2, request);
|
||||||
List<RequestKey> matches = asList(match1, match2);
|
List<RequestKey> matches = asList(match1, match2);
|
||||||
|
|
@ -86,18 +83,18 @@ public class RequestKeyComparatorTests {
|
||||||
@Test
|
@Test
|
||||||
public void oneMethodWinsOverNone() {
|
public void oneMethodWinsOverNone() {
|
||||||
Comparator<RequestKey> comparator = handlerMapping.getKeyComparator(request);
|
Comparator<RequestKey> comparator = handlerMapping.getKeyComparator(request);
|
||||||
RequestKey key1 = new RequestKey(null, null, null, null);
|
RequestKey key1 = new RequestKey(null, null);
|
||||||
RequestKey key2 = new RequestKey(null, asList(RequestMethod.GET), null, null);
|
RequestKey key2 = new RequestKey(null, asList(RequestMethod.GET));
|
||||||
|
|
||||||
assertEquals(1, comparator.compare(key1, key2));
|
assertEquals(1, comparator.compare(key1, key2));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void methodsAndParams() {
|
public void methodsAndParams() {
|
||||||
RequestKey empty = new RequestKey(null, null, null, null);
|
RequestKey empty = new RequestKey(null, null);
|
||||||
RequestKey oneMethod = new RequestKey(null, asList(RequestMethod.GET), null, null);
|
RequestKey oneMethod = new RequestKey(null, asList(RequestMethod.GET));
|
||||||
RequestKey oneMethodOneParam =
|
RequestKey oneMethodOneParam =
|
||||||
new RequestKey(null, asList(RequestMethod.GET), RequestConditionFactory.parseParams("foo"), null);
|
new RequestKey(null, asList(RequestMethod.GET), RequestConditionFactory.parseParams("foo"), null, null);
|
||||||
List<RequestKey> list = asList(empty, oneMethod, oneMethodOneParam);
|
List<RequestKey> list = asList(empty, oneMethod, oneMethodOneParam);
|
||||||
Collections.shuffle(list);
|
Collections.shuffle(list);
|
||||||
Collections.sort(list, handlerMapping.getKeyComparator(request));
|
Collections.sort(list, handlerMapping.getKeyComparator(request));
|
||||||
|
|
@ -110,9 +107,9 @@ public class RequestKeyComparatorTests {
|
||||||
@Test
|
@Test
|
||||||
@Ignore // TODO : remove ignore
|
@Ignore // TODO : remove ignore
|
||||||
public void acceptHeaders() {
|
public void acceptHeaders() {
|
||||||
RequestKey html = new RequestKey(null, null, null, RequestConditionFactory.parseHeaders("accept=text/html"));
|
RequestKey html = new RequestKey(null, null, null, RequestConditionFactory.parseHeaders("accept=text/html"), null);
|
||||||
RequestKey xml = new RequestKey(null, null, null, RequestConditionFactory.parseHeaders("accept=application/xml"));
|
RequestKey xml = new RequestKey(null, null, null, RequestConditionFactory.parseHeaders("accept=application/xml"), null);
|
||||||
RequestKey none = new RequestKey(null, null, null, null);
|
RequestKey none = new RequestKey(null, null);
|
||||||
|
|
||||||
request.addHeader("Accept", "application/xml, text/html");
|
request.addHeader("Accept", "application/xml, text/html");
|
||||||
Comparator<RequestKey> comparator = handlerMapping.getKeyComparator(request);
|
Comparator<RequestKey> comparator = handlerMapping.getKeyComparator(request);
|
||||||
|
|
|
||||||
|
|
@ -16,22 +16,20 @@
|
||||||
|
|
||||||
package org.springframework.web.servlet.mvc.method.annotation;
|
package org.springframework.web.servlet.mvc.method.annotation;
|
||||||
|
|
||||||
import static java.util.Arrays.asList;
|
|
||||||
import static org.junit.Assert.assertEquals;
|
|
||||||
import static org.junit.Assert.assertNotNull;
|
|
||||||
import static org.junit.Assert.assertNull;
|
|
||||||
import static org.springframework.web.bind.annotation.RequestMethod.GET;
|
|
||||||
import static org.springframework.web.bind.annotation.RequestMethod.POST;
|
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import org.springframework.mock.web.MockHttpServletRequest;
|
import org.springframework.mock.web.MockHttpServletRequest;
|
||||||
import org.springframework.util.AntPathMatcher;
|
import org.springframework.util.AntPathMatcher;
|
||||||
import org.springframework.util.PathMatcher;
|
import org.springframework.util.PathMatcher;
|
||||||
import org.springframework.web.bind.annotation.RequestMethod;
|
import org.springframework.web.bind.annotation.RequestMethod;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.RequestConditionFactory;
|
import org.springframework.web.servlet.mvc.method.condition.RequestConditionFactory;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.RequestKey;
|
|
||||||
import org.springframework.web.util.UrlPathHelper;
|
import org.springframework.web.util.UrlPathHelper;
|
||||||
|
|
||||||
|
import static java.util.Arrays.*;
|
||||||
|
import static java.util.Collections.*;
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
import static org.springframework.web.bind.annotation.RequestMethod.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Arjen Poutsma
|
* @author Arjen Poutsma
|
||||||
* @author Rossen Stoyanchev
|
* @author Rossen Stoyanchev
|
||||||
|
|
@ -40,8 +38,8 @@ public class RequestKeyTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void equals() {
|
public void equals() {
|
||||||
RequestKey key1 = new RequestKey(asList("/foo"), asList(GET), null, null);
|
RequestKey key1 = new RequestKey(singleton("/foo"), singleton(GET));
|
||||||
RequestKey key2 = new RequestKey(asList("/foo"), asList(GET), null, null);
|
RequestKey key2 = new RequestKey(singleton("/foo"), singleton(GET));
|
||||||
|
|
||||||
assertEquals(key1, key2);
|
assertEquals(key1, key2);
|
||||||
assertEquals(key1.hashCode(), key2.hashCode());
|
assertEquals(key1.hashCode(), key2.hashCode());
|
||||||
|
|
@ -49,8 +47,8 @@ public class RequestKeyTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void equalsPrependSlash() {
|
public void equalsPrependSlash() {
|
||||||
RequestKey key1 = new RequestKey(asList("/foo"), asList(GET), null, null);
|
RequestKey key1 = new RequestKey(singleton("/foo"), singleton(GET));
|
||||||
RequestKey key2 = new RequestKey(asList("foo"), asList(GET), null, null);
|
RequestKey key2 = new RequestKey(singleton("foo"), singleton(GET));
|
||||||
|
|
||||||
assertEquals(key1, key2);
|
assertEquals(key1, key2);
|
||||||
assertEquals(key1.hashCode(), key2.hashCode());
|
assertEquals(key1.hashCode(), key2.hashCode());
|
||||||
|
|
@ -63,22 +61,22 @@ public class RequestKeyTests {
|
||||||
RequestKey key1 = createKeyFromPatterns("/t1", "/t2");
|
RequestKey key1 = createKeyFromPatterns("/t1", "/t2");
|
||||||
RequestKey key2 = createKeyFromPatterns("/m1", "/m2");
|
RequestKey key2 = createKeyFromPatterns("/m1", "/m2");
|
||||||
RequestKey key3 = createKeyFromPatterns("/t1/m1", "/t1/m2", "/t2/m1", "/t2/m2");
|
RequestKey key3 = createKeyFromPatterns("/t1/m1", "/t1/m2", "/t2/m1", "/t2/m2");
|
||||||
assertEquals(key3, key1.combine(key2, pathMatcher));
|
assertEquals(key3.getPatterns(), key1.combine(key2, pathMatcher).getPatterns());
|
||||||
|
|
||||||
key1 = createKeyFromPatterns("/t1");
|
key1 = createKeyFromPatterns("/t1");
|
||||||
key2 = createKeyFromPatterns(new String[] {});
|
key2 = createKeyFromPatterns();
|
||||||
key3 = createKeyFromPatterns("/t1");
|
key3 = createKeyFromPatterns("/t1");
|
||||||
assertEquals(key3, key1.combine(key2, pathMatcher));
|
assertEquals(key3.getPatterns(), key1.combine(key2, pathMatcher).getPatterns());
|
||||||
|
|
||||||
key1 = createKeyFromPatterns(new String[] {});
|
key1 = createKeyFromPatterns();
|
||||||
key2 = createKeyFromPatterns("/m1");
|
key2 = createKeyFromPatterns("/m1");
|
||||||
key3 = createKeyFromPatterns("/m1");
|
key3 = createKeyFromPatterns("/m1");
|
||||||
assertEquals(key3, key1.combine(key2, pathMatcher));
|
assertEquals(key3.getPatterns(), key1.combine(key2, pathMatcher).getPatterns());
|
||||||
|
|
||||||
key1 = createKeyFromPatterns(new String[] {});
|
key1 = createKeyFromPatterns();
|
||||||
key2 = createKeyFromPatterns(new String[] {});
|
key2 = createKeyFromPatterns();
|
||||||
key3 = createKeyFromPatterns("/");
|
key3 = createKeyFromPatterns("/");
|
||||||
assertEquals(key3, key1.combine(key2, pathMatcher));
|
assertEquals(key3.getPatterns(), key1.combine(key2, pathMatcher).getPatterns());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -88,39 +86,39 @@ public class RequestKeyTests {
|
||||||
PathMatcher pathMatcher = new AntPathMatcher();
|
PathMatcher pathMatcher = new AntPathMatcher();
|
||||||
|
|
||||||
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/foo");
|
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/foo");
|
||||||
RequestKey key = new RequestKey(asList("/foo"), null, null, null);
|
RequestKey key = new RequestKey(singleton("/foo"), null);
|
||||||
RequestKey match = key.getMatchingKey(request, pathMatcher, urlPathHelper);
|
RequestKey match = key.getMatchingKey(request, pathMatcher, urlPathHelper);
|
||||||
|
|
||||||
assertNotNull(match);
|
assertNotNull(match);
|
||||||
|
|
||||||
request = new MockHttpServletRequest("GET", "/foo/bar");
|
request = new MockHttpServletRequest("GET", "/foo/bar");
|
||||||
key = new RequestKey(asList("/foo/*"), null, null, null);
|
key = new RequestKey(singleton("/foo/*"), null);
|
||||||
match = key.getMatchingKey(request, pathMatcher, urlPathHelper);
|
match = key.getMatchingKey(request, pathMatcher, urlPathHelper);
|
||||||
|
|
||||||
assertNotNull("Pattern match", match);
|
assertNotNull("Pattern match", match);
|
||||||
|
|
||||||
request = new MockHttpServletRequest("GET", "/foo.html");
|
request = new MockHttpServletRequest("GET", "/foo.html");
|
||||||
key = new RequestKey(asList("/foo"), null, null, null);
|
key = new RequestKey(singleton("/foo"), null);
|
||||||
match = key.getMatchingKey(request, pathMatcher, urlPathHelper);
|
match = key.getMatchingKey(request, pathMatcher, urlPathHelper);
|
||||||
|
|
||||||
assertNotNull("Implicit match by extension", match);
|
assertNotNull("Implicit match by extension", match);
|
||||||
assertEquals("Contains matched pattern", "/foo.*", match.getPatterns().iterator().next());
|
assertEquals("Contains matched pattern", "/foo.*", match.getPatterns().iterator().next());
|
||||||
|
|
||||||
request = new MockHttpServletRequest("GET", "/foo/");
|
request = new MockHttpServletRequest("GET", "/foo/");
|
||||||
key = new RequestKey(asList("/foo"), null, null, null);
|
key = new RequestKey(singleton("/foo"), null);
|
||||||
match = key.getMatchingKey(request, pathMatcher, urlPathHelper);
|
match = key.getMatchingKey(request, pathMatcher, urlPathHelper);
|
||||||
|
|
||||||
assertNotNull("Implicit match by trailing slash", match);
|
assertNotNull("Implicit match by trailing slash", match);
|
||||||
assertEquals("Contains matched pattern", "/foo/", match.getPatterns().iterator().next());
|
assertEquals("Contains matched pattern", "/foo/", match.getPatterns().iterator().next());
|
||||||
|
|
||||||
request = new MockHttpServletRequest("GET", "/foo.html");
|
request = new MockHttpServletRequest("GET", "/foo.html");
|
||||||
key = new RequestKey(asList("/foo.jpg"), null, null, null);
|
key = new RequestKey(singleton("/foo.jpg"), null);
|
||||||
match = key.getMatchingKey(request, pathMatcher, urlPathHelper);
|
match = key.getMatchingKey(request, pathMatcher, urlPathHelper);
|
||||||
|
|
||||||
assertNull("Implicit match ignored if pattern has extension", match);
|
assertNull("Implicit match ignored if pattern has extension", match);
|
||||||
|
|
||||||
request = new MockHttpServletRequest("GET", "/foo.html");
|
request = new MockHttpServletRequest("GET", "/foo.html");
|
||||||
key = new RequestKey(asList("/foo.jpg"), null, null, null);
|
key = new RequestKey(singleton("/foo.jpg"), null);
|
||||||
match = key.getMatchingKey(request, pathMatcher, urlPathHelper);
|
match = key.getMatchingKey(request, pathMatcher, urlPathHelper);
|
||||||
|
|
||||||
assertNull("Implicit match ignored on pattern with trailing slash", match);
|
assertNull("Implicit match ignored on pattern with trailing slash", match);
|
||||||
|
|
@ -132,17 +130,17 @@ public class RequestKeyTests {
|
||||||
PathMatcher pathMatcher = new AntPathMatcher();
|
PathMatcher pathMatcher = new AntPathMatcher();
|
||||||
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/foo");
|
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/foo");
|
||||||
|
|
||||||
RequestKey key = new RequestKey(asList("/foo"), null, null, null);
|
RequestKey key = new RequestKey(singleton("/foo"), null);
|
||||||
RequestKey match = key.getMatchingKey(request, pathMatcher, urlPathHelper);
|
RequestKey match = key.getMatchingKey(request, pathMatcher, urlPathHelper);
|
||||||
|
|
||||||
assertNotNull("No method matches any method", match);
|
assertNotNull("No method matches any method", match);
|
||||||
|
|
||||||
key = new RequestKey(asList("/foo"), asList(GET), null, null);
|
key = new RequestKey(singleton("/foo"), singleton(GET));
|
||||||
match = key.getMatchingKey(request, pathMatcher, urlPathHelper);
|
match = key.getMatchingKey(request, pathMatcher, urlPathHelper);
|
||||||
|
|
||||||
assertNotNull("Exact match", match);
|
assertNotNull("Exact match", match);
|
||||||
|
|
||||||
key = new RequestKey(asList("/foo"), asList(POST), null, null);
|
key = new RequestKey(singleton("/foo"), singleton(POST));
|
||||||
match = key.getMatchingKey(request, pathMatcher, urlPathHelper);
|
match = key.getMatchingKey(request, pathMatcher, urlPathHelper);
|
||||||
|
|
||||||
assertNull("No match", match);
|
assertNull("No match", match);
|
||||||
|
|
@ -154,15 +152,15 @@ public class RequestKeyTests {
|
||||||
PathMatcher pathMatcher = new AntPathMatcher();
|
PathMatcher pathMatcher = new AntPathMatcher();
|
||||||
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/foo");
|
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/foo");
|
||||||
|
|
||||||
RequestKey key = new RequestKey(asList("/foo*", "/bar"), asList(GET, POST), null, null);
|
RequestKey key = new RequestKey(asList("/foo*", "/bar"), asList(GET, POST));
|
||||||
RequestKey match = key.getMatchingKey(request, pathMatcher, urlPathHelper);
|
RequestKey match = key.getMatchingKey(request, pathMatcher, urlPathHelper);
|
||||||
RequestKey expected = new RequestKey(asList("/foo*"), asList(GET), null, null);
|
RequestKey expected = new RequestKey(singleton("/foo*"), singleton(GET));
|
||||||
|
|
||||||
assertEquals("Matching RequestKey contains matched patterns and methods only", expected, match);
|
assertEquals("Matching RequestKey contains matched patterns and methods only", expected, match);
|
||||||
|
|
||||||
key = new RequestKey(asList("/**", "/foo*", "/foo"), null, null, null);
|
key = new RequestKey(asList("/**", "/foo*", "/foo"), null);
|
||||||
match = key.getMatchingKey(request, pathMatcher, urlPathHelper);
|
match = key.getMatchingKey(request, pathMatcher, urlPathHelper);
|
||||||
expected = new RequestKey(asList("/foo", "/foo*", "/**"), null, null, null);
|
expected = new RequestKey(asList("/foo", "/foo*", "/**"), null);
|
||||||
|
|
||||||
assertEquals("Matched patterns are sorted with best match at the top", expected, match);
|
assertEquals("Matched patterns are sorted with best match at the top", expected, match);
|
||||||
|
|
||||||
|
|
@ -175,12 +173,12 @@ public class RequestKeyTests {
|
||||||
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/foo");
|
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/foo");
|
||||||
request.setParameter("foo", "bar");
|
request.setParameter("foo", "bar");
|
||||||
|
|
||||||
RequestKey key = new RequestKey(asList("/foo"), null, RequestConditionFactory.parseParams("foo=bar"), null);
|
RequestKey key = new RequestKey(asList("/foo"), null, RequestConditionFactory.parseParams("foo=bar"), null, null);
|
||||||
RequestKey match = key.getMatchingKey(request, pathMatcher, urlPathHelper);
|
RequestKey match = key.getMatchingKey(request, pathMatcher, urlPathHelper);
|
||||||
|
|
||||||
assertNotNull(match);
|
assertNotNull(match);
|
||||||
|
|
||||||
key = new RequestKey(asList("/foo"), null, RequestConditionFactory.parseParams("foo!=bar"), null);
|
key = new RequestKey(singleton("/foo"), null, RequestConditionFactory.parseParams("foo!=bar"), null, null);
|
||||||
match = key.getMatchingKey(request, pathMatcher, urlPathHelper);
|
match = key.getMatchingKey(request, pathMatcher, urlPathHelper);
|
||||||
|
|
||||||
assertNull(match);
|
assertNull(match);
|
||||||
|
|
@ -193,12 +191,12 @@ public class RequestKeyTests {
|
||||||
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/foo");
|
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/foo");
|
||||||
request.addHeader("foo", "bar");
|
request.addHeader("foo", "bar");
|
||||||
|
|
||||||
RequestKey key = new RequestKey(asList("/foo"), null, null, RequestConditionFactory.parseHeaders("foo=bar"));
|
RequestKey key = new RequestKey(singleton("/foo"), null, null, RequestConditionFactory.parseHeaders("foo=bar"), null);
|
||||||
RequestKey match = key.getMatchingKey(request, pathMatcher, urlPathHelper);
|
RequestKey match = key.getMatchingKey(request, pathMatcher, urlPathHelper);
|
||||||
|
|
||||||
assertNotNull(match);
|
assertNotNull(match);
|
||||||
|
|
||||||
key = new RequestKey(asList("/foo"), null, null, RequestConditionFactory.parseHeaders("foo!=bar"));
|
key = new RequestKey(singleton("/foo"), null, null, RequestConditionFactory.parseHeaders("foo!=bar"), null);
|
||||||
match = key.getMatchingKey(request, pathMatcher, urlPathHelper);
|
match = key.getMatchingKey(request, pathMatcher, urlPathHelper);
|
||||||
|
|
||||||
assertNull(match);
|
assertNull(match);
|
||||||
|
|
@ -208,11 +206,11 @@ public class RequestKeyTests {
|
||||||
public void testCreateFromServletRequest() {
|
public void testCreateFromServletRequest() {
|
||||||
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/foo");
|
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/foo");
|
||||||
RequestKey key = RequestKey.createFromServletRequest(request, new UrlPathHelper());
|
RequestKey key = RequestKey.createFromServletRequest(request, new UrlPathHelper());
|
||||||
assertEquals(new RequestKey(asList("/foo"), asList(RequestMethod.GET), null, null), key);
|
assertEquals(new RequestKey(singleton("/foo"), singleton(RequestMethod.GET), null, null, null), key);
|
||||||
}
|
}
|
||||||
|
|
||||||
private RequestKey createKeyFromPatterns(String... patterns) {
|
private RequestKey createKeyFromPatterns(String... patterns) {
|
||||||
return new RequestKey(asList(patterns), null, null, null);
|
return new RequestKey(asList(patterns), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,20 +16,13 @@
|
||||||
|
|
||||||
package org.springframework.web.servlet.mvc.method.annotation;
|
package org.springframework.web.servlet.mvc.method.annotation;
|
||||||
|
|
||||||
import static org.junit.Assert.assertArrayEquals;
|
|
||||||
import static org.junit.Assert.assertEquals;
|
|
||||||
import static org.junit.Assert.assertNotNull;
|
|
||||||
import static org.junit.Assert.assertNull;
|
|
||||||
import static org.junit.Assert.assertSame;
|
|
||||||
import static org.junit.Assert.fail;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import org.springframework.context.support.StaticApplicationContext;
|
import org.springframework.context.support.StaticApplicationContext;
|
||||||
import org.springframework.mock.web.MockHttpServletRequest;
|
import org.springframework.mock.web.MockHttpServletRequest;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
|
|
@ -42,8 +35,8 @@ import org.springframework.web.servlet.HandlerInterceptor;
|
||||||
import org.springframework.web.servlet.HandlerMapping;
|
import org.springframework.web.servlet.HandlerMapping;
|
||||||
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
|
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
|
||||||
import org.springframework.web.servlet.handler.MappedInterceptor;
|
import org.springframework.web.servlet.handler.MappedInterceptor;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.RequestKey;
|
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMethodMapping;
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Arjen Poutsma
|
* @author Arjen Poutsma
|
||||||
|
|
@ -96,7 +89,7 @@ public class RequestMappingHandlerMethodMappingTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void uriTemplateVariables() {
|
public void uriTemplateVariables() {
|
||||||
RequestKey key = new RequestKey(Arrays.asList("/{path1}/{path2}"), null, null, null);
|
RequestKey key = new RequestKey(Arrays.asList("/{path1}/{path2}"), null);
|
||||||
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/1/2");
|
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/1/2");
|
||||||
|
|
||||||
mapping.handleMatch(key, request);
|
mapping.handleMatch(key, request);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,212 @@
|
||||||
|
/*
|
||||||
|
* 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));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2010 the original author or authors.
|
* Copyright 2002-2011 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
@ -297,4 +297,6 @@ public @interface RequestMapping {
|
||||||
*/
|
*/
|
||||||
String[] headers() default {};
|
String[] headers() default {};
|
||||||
|
|
||||||
|
String[] consumes() default "*/*";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue