Merge branch '5.2.x'
This commit is contained in:
@@ -30,6 +30,7 @@ import org.springframework.http.InvalidMediaTypeException;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.cors.CorsUtils;
|
||||
@@ -76,12 +77,34 @@ public final class ConsumesRequestCondition extends AbstractRequestCondition<Con
|
||||
* @param headers as described in {@link RequestMapping#headers()}
|
||||
*/
|
||||
public ConsumesRequestCondition(String[] consumes, @Nullable String[] headers) {
|
||||
this.expressions = new ArrayList<>(parseExpressions(consumes, headers));
|
||||
this.expressions = parseExpressions(consumes, headers);
|
||||
if (this.expressions.size() > 1) {
|
||||
Collections.sort(this.expressions);
|
||||
}
|
||||
}
|
||||
|
||||
private static List<ConsumeMediaTypeExpression> parseExpressions(String[] consumes, @Nullable String[] headers) {
|
||||
Set<ConsumeMediaTypeExpression> result = null;
|
||||
if (!ObjectUtils.isEmpty(headers)) {
|
||||
for (String header : headers) {
|
||||
HeaderExpression expr = new HeaderExpression(header);
|
||||
if ("Content-Type".equalsIgnoreCase(expr.name) && expr.value != null) {
|
||||
result = (result != null ? result : new LinkedHashSet<>());
|
||||
for (MediaType mediaType : MediaType.parseMediaTypes(expr.value)) {
|
||||
result.add(new ConsumeMediaTypeExpression(mediaType, expr.isNegated));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!ObjectUtils.isEmpty(consumes)) {
|
||||
result = (result != null ? result : new LinkedHashSet<>());
|
||||
for (String consume : consumes) {
|
||||
result.add(new ConsumeMediaTypeExpression(consume));
|
||||
}
|
||||
}
|
||||
return (result != null ? new ArrayList<>(result) : Collections.emptyList());
|
||||
}
|
||||
|
||||
/**
|
||||
* Private constructor for internal when creating matching conditions.
|
||||
* Note the expressions List is neither sorted nor deep copied.
|
||||
@@ -91,25 +114,6 @@ public final class ConsumesRequestCondition extends AbstractRequestCondition<Con
|
||||
}
|
||||
|
||||
|
||||
private static Set<ConsumeMediaTypeExpression> parseExpressions(String[] consumes, @Nullable String[] headers) {
|
||||
Set<ConsumeMediaTypeExpression> result = new LinkedHashSet<>();
|
||||
if (headers != null) {
|
||||
for (String header : headers) {
|
||||
HeaderExpression expr = new HeaderExpression(header);
|
||||
if ("Content-Type".equalsIgnoreCase(expr.name) && expr.value != null) {
|
||||
for (MediaType mediaType : MediaType.parseMediaTypes(expr.value)) {
|
||||
result.add(new ConsumeMediaTypeExpression(mediaType, expr.isNegated));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (String consume : consumes) {
|
||||
result.add(new ConsumeMediaTypeExpression(consume));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the contained MediaType expressions.
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2020 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.
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.springframework.web.servlet.mvc.condition;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
@@ -55,7 +56,22 @@ public final class HeadersRequestCondition extends AbstractRequestCondition<Head
|
||||
* if 0, the condition will match to every request
|
||||
*/
|
||||
public HeadersRequestCondition(String... headers) {
|
||||
this(parseExpressions(headers));
|
||||
this.expressions = parseExpressions(headers);
|
||||
}
|
||||
|
||||
private static Set<HeaderExpression> parseExpressions(String... headers) {
|
||||
Set<HeaderExpression> result = null;
|
||||
if (!ObjectUtils.isEmpty(headers)) {
|
||||
for (String header : headers) {
|
||||
HeaderExpression expr = new HeaderExpression(header);
|
||||
if ("Accept".equalsIgnoreCase(expr.name) || "Content-Type".equalsIgnoreCase(expr.name)) {
|
||||
continue;
|
||||
}
|
||||
result = (result != null ? result : new LinkedHashSet<>(headers.length));
|
||||
result.add(expr);
|
||||
}
|
||||
}
|
||||
return (result != null ? result : Collections.emptySet());
|
||||
}
|
||||
|
||||
private HeadersRequestCondition(Set<HeaderExpression> conditions) {
|
||||
@@ -63,18 +79,6 @@ public final class HeadersRequestCondition extends AbstractRequestCondition<Head
|
||||
}
|
||||
|
||||
|
||||
private static Set<HeaderExpression> parseExpressions(String... headers) {
|
||||
Set<HeaderExpression> expressions = new LinkedHashSet<>();
|
||||
for (String header : headers) {
|
||||
HeaderExpression expr = new HeaderExpression(header);
|
||||
if ("Accept".equalsIgnoreCase(expr.name) || "Content-Type".equalsIgnoreCase(expr.name)) {
|
||||
continue;
|
||||
}
|
||||
expressions.add(expr);
|
||||
}
|
||||
return expressions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the contained request header expressions.
|
||||
*/
|
||||
@@ -98,6 +102,15 @@ public final class HeadersRequestCondition extends AbstractRequestCondition<Head
|
||||
*/
|
||||
@Override
|
||||
public HeadersRequestCondition combine(HeadersRequestCondition other) {
|
||||
if (isEmpty() && other.isEmpty()) {
|
||||
return this;
|
||||
}
|
||||
else if (other.isEmpty()) {
|
||||
return this;
|
||||
}
|
||||
else if (isEmpty()) {
|
||||
return other;
|
||||
}
|
||||
Set<HeaderExpression> set = new LinkedHashSet<>(this.expressions);
|
||||
set.addAll(other.expressions);
|
||||
return new HeadersRequestCondition(set);
|
||||
@@ -157,7 +170,7 @@ public final class HeadersRequestCondition extends AbstractRequestCondition<Head
|
||||
*/
|
||||
static class HeaderExpression extends AbstractNameValueExpression<String> {
|
||||
|
||||
public HeaderExpression(String expression) {
|
||||
HeaderExpression(String expression) {
|
||||
super(expression);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2020 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.
|
||||
@@ -48,22 +48,24 @@ public final class ParamsRequestCondition extends AbstractRequestCondition<Param
|
||||
* if 0, the condition will match to every request.
|
||||
*/
|
||||
public ParamsRequestCondition(String... params) {
|
||||
this(parseExpressions(params));
|
||||
this.expressions = parseExpressions(params);
|
||||
}
|
||||
|
||||
private ParamsRequestCondition(Collection<ParamExpression> conditions) {
|
||||
this.expressions = Collections.unmodifiableSet(new LinkedHashSet<>(conditions));
|
||||
}
|
||||
|
||||
|
||||
private static Collection<ParamExpression> parseExpressions(String... params) {
|
||||
Set<ParamExpression> expressions = new LinkedHashSet<>();
|
||||
private static Set<ParamExpression> parseExpressions(String... params) {
|
||||
if (ObjectUtils.isEmpty(params)) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
Set<ParamExpression> expressions = new LinkedHashSet<>(params.length);
|
||||
for (String param : params) {
|
||||
expressions.add(new ParamExpression(param));
|
||||
}
|
||||
return expressions;
|
||||
}
|
||||
|
||||
private ParamsRequestCondition(Set<ParamExpression> conditions) {
|
||||
this.expressions = conditions;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the contained request parameter expressions.
|
||||
@@ -88,6 +90,15 @@ public final class ParamsRequestCondition extends AbstractRequestCondition<Param
|
||||
*/
|
||||
@Override
|
||||
public ParamsRequestCondition combine(ParamsRequestCondition other) {
|
||||
if (isEmpty() && other.isEmpty()) {
|
||||
return this;
|
||||
}
|
||||
else if (other.isEmpty()) {
|
||||
return this;
|
||||
}
|
||||
else if (isEmpty()) {
|
||||
return other;
|
||||
}
|
||||
Set<ParamExpression> set = new LinkedHashSet<>(this.expressions);
|
||||
set.addAll(other.expressions);
|
||||
return new ParamsRequestCondition(set);
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
package org.springframework.web.servlet.mvc.condition;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
@@ -30,6 +29,7 @@ import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.AntPathMatcher;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.PathMatcher;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.servlet.HandlerMapping;
|
||||
@@ -42,7 +42,10 @@ import org.springframework.web.util.UrlPathHelper;
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 3.1
|
||||
*/
|
||||
public final class PatternsRequestCondition extends AbstractRequestCondition<PatternsRequestCondition> {
|
||||
public class PatternsRequestCondition extends AbstractRequestCondition<PatternsRequestCondition> {
|
||||
|
||||
private final static Set<String> EMPTY_PATH_PATTERN = Collections.singleton("");
|
||||
|
||||
|
||||
private final Set<String> patterns;
|
||||
|
||||
@@ -64,7 +67,7 @@ public final class PatternsRequestCondition extends AbstractRequestCondition<Pat
|
||||
* every request.
|
||||
*/
|
||||
public PatternsRequestCondition(String... patterns) {
|
||||
this(Arrays.asList(patterns), null, null, true, true, null);
|
||||
this(patterns, null, null, true, true, null);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -79,7 +82,7 @@ public final class PatternsRequestCondition extends AbstractRequestCondition<Pat
|
||||
public PatternsRequestCondition(String[] patterns, @Nullable UrlPathHelper urlPathHelper,
|
||||
@Nullable PathMatcher pathMatcher, boolean useTrailingSlashMatch) {
|
||||
|
||||
this(Arrays.asList(patterns), urlPathHelper, pathMatcher, false, useTrailingSlashMatch, null);
|
||||
this(patterns, urlPathHelper, pathMatcher, false, useTrailingSlashMatch, null);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -97,7 +100,7 @@ public final class PatternsRequestCondition extends AbstractRequestCondition<Pat
|
||||
public PatternsRequestCondition(String[] patterns, @Nullable UrlPathHelper urlPathHelper,
|
||||
@Nullable PathMatcher pathMatcher, boolean useSuffixPatternMatch, boolean useTrailingSlashMatch) {
|
||||
|
||||
this(Arrays.asList(patterns), urlPathHelper, pathMatcher, useSuffixPatternMatch, useTrailingSlashMatch, null);
|
||||
this(patterns, urlPathHelper, pathMatcher, useSuffixPatternMatch, useTrailingSlashMatch, null);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -117,18 +120,7 @@ public final class PatternsRequestCondition extends AbstractRequestCondition<Pat
|
||||
@Nullable PathMatcher pathMatcher, boolean useSuffixPatternMatch,
|
||||
boolean useTrailingSlashMatch, @Nullable List<String> fileExtensions) {
|
||||
|
||||
this(Arrays.asList(patterns), urlPathHelper, pathMatcher, useSuffixPatternMatch,
|
||||
useTrailingSlashMatch, fileExtensions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Private constructor accepting a collection of patterns.
|
||||
*/
|
||||
private PatternsRequestCondition(Collection<String> patterns, @Nullable UrlPathHelper urlPathHelper,
|
||||
@Nullable PathMatcher pathMatcher, boolean useSuffixPatternMatch,
|
||||
boolean useTrailingSlashMatch, @Nullable List<String> fileExtensions) {
|
||||
|
||||
this.patterns = Collections.unmodifiableSet(prependLeadingSlash(patterns));
|
||||
this.patterns = initPatterns(patterns);
|
||||
this.pathHelper = urlPathHelper != null ? urlPathHelper : UrlPathHelper.defaultInstance;
|
||||
this.pathMatcher = pathMatcher != null ? pathMatcher : new AntPathMatcher();
|
||||
this.useSuffixPatternMatch = useSuffixPatternMatch;
|
||||
@@ -144,6 +136,31 @@ public final class PatternsRequestCondition extends AbstractRequestCondition<Pat
|
||||
}
|
||||
}
|
||||
|
||||
private static Set<String> initPatterns(String[] patterns) {
|
||||
if (!hasPattern(patterns)) {
|
||||
return EMPTY_PATH_PATTERN;
|
||||
}
|
||||
Set<String> result = new LinkedHashSet<>(patterns.length);
|
||||
for (String pattern : patterns) {
|
||||
if (StringUtils.hasLength(pattern) && !pattern.startsWith("/")) {
|
||||
pattern = "/" + pattern;
|
||||
}
|
||||
result.add(pattern);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static boolean hasPattern(String[] patterns) {
|
||||
if (!ObjectUtils.isEmpty(patterns)) {
|
||||
for (String pattern : patterns) {
|
||||
if (StringUtils.hasText(pattern)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Private constructor for use when combining and matching.
|
||||
*/
|
||||
@@ -157,20 +174,6 @@ public final class PatternsRequestCondition extends AbstractRequestCondition<Pat
|
||||
}
|
||||
|
||||
|
||||
private static Set<String> prependLeadingSlash(Collection<String> patterns) {
|
||||
if (patterns.isEmpty()) {
|
||||
return Collections.singleton("");
|
||||
}
|
||||
Set<String> result = new LinkedHashSet<>(patterns.size());
|
||||
for (String pattern : patterns) {
|
||||
if (StringUtils.hasLength(pattern) && !pattern.startsWith("/")) {
|
||||
pattern = "/" + pattern;
|
||||
}
|
||||
result.add(pattern);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public Set<String> getPatterns() {
|
||||
return this.patterns;
|
||||
}
|
||||
@@ -197,6 +200,15 @@ public final class PatternsRequestCondition extends AbstractRequestCondition<Pat
|
||||
*/
|
||||
@Override
|
||||
public PatternsRequestCondition combine(PatternsRequestCondition other) {
|
||||
if (isEmptyPathPattern() && other.isEmptyPathPattern()) {
|
||||
return this;
|
||||
}
|
||||
else if (other.isEmptyPathPattern()) {
|
||||
return this;
|
||||
}
|
||||
else if (isEmptyPathPattern()) {
|
||||
return other;
|
||||
}
|
||||
Set<String> result = new LinkedHashSet<>();
|
||||
if (!this.patterns.isEmpty() && !other.patterns.isEmpty()) {
|
||||
for (String pattern1 : this.patterns) {
|
||||
@@ -205,18 +217,13 @@ public final class PatternsRequestCondition extends AbstractRequestCondition<Pat
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!this.patterns.isEmpty()) {
|
||||
result.addAll(this.patterns);
|
||||
}
|
||||
else if (!other.patterns.isEmpty()) {
|
||||
result.addAll(other.patterns);
|
||||
}
|
||||
else {
|
||||
result.add("");
|
||||
}
|
||||
return new PatternsRequestCondition(result, this);
|
||||
}
|
||||
|
||||
private boolean isEmptyPathPattern() {
|
||||
return this.patterns == EMPTY_PATH_PATTERN;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if any of the patterns match the given request and returns an instance
|
||||
* that is guaranteed to contain matching patterns, sorted via
|
||||
@@ -236,9 +243,6 @@ public final class PatternsRequestCondition extends AbstractRequestCondition<Pat
|
||||
@Override
|
||||
@Nullable
|
||||
public PatternsRequestCondition getMatchingCondition(HttpServletRequest request) {
|
||||
if (this.patterns.isEmpty()) {
|
||||
return this;
|
||||
}
|
||||
String lookupPath = this.pathHelper.getLookupPathForRequest(request, HandlerMapping.LOOKUP_PATH);
|
||||
List<String> matches = getMatchingPatterns(lookupPath);
|
||||
return !matches.isEmpty() ? new PatternsRequestCondition(new LinkedHashSet<>(matches), this) : null;
|
||||
@@ -257,7 +261,7 @@ public final class PatternsRequestCondition extends AbstractRequestCondition<Pat
|
||||
for (String pattern : this.patterns) {
|
||||
String match = getMatchingPattern(pattern, lookupPath);
|
||||
if (match != null) {
|
||||
matches = matches != null ? matches : new ArrayList<>();
|
||||
matches = (matches != null ? matches : new ArrayList<>());
|
||||
matches.add(match);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ import javax.servlet.http.HttpServletRequest;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.HttpMediaTypeException;
|
||||
import org.springframework.web.HttpMediaTypeNotAcceptableException;
|
||||
@@ -96,13 +97,35 @@ public final class ProducesRequestCondition extends AbstractRequestCondition<Pro
|
||||
public ProducesRequestCondition(String[] produces, @Nullable String[] headers,
|
||||
@Nullable ContentNegotiationManager manager) {
|
||||
|
||||
this.expressions = new ArrayList<>(parseExpressions(produces, headers));
|
||||
this.expressions = parseExpressions(produces, headers);
|
||||
if (this.expressions.size() > 1) {
|
||||
Collections.sort(this.expressions);
|
||||
}
|
||||
this.contentNegotiationManager = manager != null ? manager : DEFAULT_CONTENT_NEGOTIATION_MANAGER;
|
||||
}
|
||||
|
||||
private List<ProduceMediaTypeExpression> parseExpressions(String[] produces, @Nullable String[] headers) {
|
||||
Set<ProduceMediaTypeExpression> result = null;
|
||||
if (!ObjectUtils.isEmpty(headers)) {
|
||||
for (String header : headers) {
|
||||
HeaderExpression expr = new HeaderExpression(header);
|
||||
if ("Accept".equalsIgnoreCase(expr.name) && expr.value != null) {
|
||||
for (MediaType mediaType : MediaType.parseMediaTypes(expr.value)) {
|
||||
result = (result != null ? result : new LinkedHashSet<>());
|
||||
result.add(new ProduceMediaTypeExpression(mediaType, expr.isNegated));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!ObjectUtils.isEmpty(produces)) {
|
||||
for (String produce : produces) {
|
||||
result = (result != null ? result : new LinkedHashSet<>());
|
||||
result.add(new ProduceMediaTypeExpression(produce));
|
||||
}
|
||||
}
|
||||
return (result != null ? new ArrayList<>(result) : Collections.emptyList());
|
||||
}
|
||||
|
||||
/**
|
||||
* Private constructor for internal use to create matching conditions.
|
||||
* Note the expressions List is neither sorted nor deep copied.
|
||||
@@ -113,24 +136,6 @@ public final class ProducesRequestCondition extends AbstractRequestCondition<Pro
|
||||
}
|
||||
|
||||
|
||||
private Set<ProduceMediaTypeExpression> parseExpressions(String[] produces, @Nullable String[] headers) {
|
||||
Set<ProduceMediaTypeExpression> result = new LinkedHashSet<>();
|
||||
if (headers != null) {
|
||||
for (String header : headers) {
|
||||
HeaderExpression expr = new HeaderExpression(header);
|
||||
if ("Accept".equalsIgnoreCase(expr.name) && expr.value != null) {
|
||||
for (MediaType mediaType : MediaType.parseMediaTypes(expr.value)) {
|
||||
result.add(new ProduceMediaTypeExpression(mediaType, expr.isNegated));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (String produce : produces) {
|
||||
result.add(new ProduceMediaTypeExpression(produce));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the contained "produces" expressions.
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2020 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.
|
||||
@@ -30,6 +30,7 @@ import javax.servlet.http.HttpServletRequest;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.cors.CorsUtils;
|
||||
|
||||
@@ -63,11 +64,15 @@ public final class RequestMethodsRequestCondition extends AbstractRequestConditi
|
||||
* if, 0 the condition will match to every request
|
||||
*/
|
||||
public RequestMethodsRequestCondition(RequestMethod... requestMethods) {
|
||||
this(Arrays.asList(requestMethods));
|
||||
this.methods = (ObjectUtils.isEmpty(requestMethods) ?
|
||||
Collections.emptySet() : new LinkedHashSet<>(Arrays.asList(requestMethods)));
|
||||
}
|
||||
|
||||
private RequestMethodsRequestCondition(Collection<RequestMethod> requestMethods) {
|
||||
this.methods = Collections.unmodifiableSet(new LinkedHashSet<>(requestMethods));
|
||||
/**
|
||||
* Private constructor for internal use when combining conditions.
|
||||
*/
|
||||
private RequestMethodsRequestCondition(Set<RequestMethod> methods) {
|
||||
this.methods = methods;
|
||||
}
|
||||
|
||||
|
||||
@@ -94,6 +99,15 @@ public final class RequestMethodsRequestCondition extends AbstractRequestConditi
|
||||
*/
|
||||
@Override
|
||||
public RequestMethodsRequestCondition combine(RequestMethodsRequestCondition other) {
|
||||
if (isEmpty() && other.isEmpty()) {
|
||||
return this;
|
||||
}
|
||||
else if (other.isEmpty()) {
|
||||
return this;
|
||||
}
|
||||
else if (isEmpty()) {
|
||||
return other;
|
||||
}
|
||||
Set<RequestMethod> set = new LinkedHashSet<>(this.methods);
|
||||
set.addAll(other.methods);
|
||||
return new RequestMethodsRequestCondition(set);
|
||||
|
||||
@@ -23,6 +23,7 @@ import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.PathMatcher;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.accept.ContentNegotiationManager;
|
||||
@@ -56,6 +57,19 @@ import org.springframework.web.util.UrlPathHelper;
|
||||
*/
|
||||
public final class RequestMappingInfo implements RequestCondition<RequestMappingInfo> {
|
||||
|
||||
private static final PatternsRequestCondition EMPTY_PATTERNS = new PatternsRequestCondition();
|
||||
|
||||
private static final RequestMethodsRequestCondition EMPTY_REQUEST_METHODS = new RequestMethodsRequestCondition();
|
||||
|
||||
private static final ParamsRequestCondition EMPTY_PARAMS = new ParamsRequestCondition();
|
||||
|
||||
private static final HeadersRequestCondition EMPTY_HEADERS = new HeadersRequestCondition();
|
||||
|
||||
private static final ConsumesRequestCondition EMPTY_CONSUMES = new ConsumesRequestCondition();
|
||||
|
||||
private static final ProducesRequestCondition EMPTY_PRODUCES = new ProducesRequestCondition();
|
||||
|
||||
|
||||
@Nullable
|
||||
private final String name;
|
||||
|
||||
@@ -80,12 +94,12 @@ public final class RequestMappingInfo implements RequestCondition<RequestMapping
|
||||
@Nullable ProducesRequestCondition produces, @Nullable RequestCondition<?> custom) {
|
||||
|
||||
this.name = (StringUtils.hasText(name) ? name : null);
|
||||
this.patternsCondition = (patterns != null ? patterns : new PatternsRequestCondition());
|
||||
this.methodsCondition = (methods != null ? methods : new RequestMethodsRequestCondition());
|
||||
this.paramsCondition = (params != null ? params : new ParamsRequestCondition());
|
||||
this.headersCondition = (headers != null ? headers : new HeadersRequestCondition());
|
||||
this.consumesCondition = (consumes != null ? consumes : new ConsumesRequestCondition());
|
||||
this.producesCondition = (produces != null ? produces : new ProducesRequestCondition());
|
||||
this.patternsCondition = (patterns != null ? patterns : EMPTY_PATTERNS);
|
||||
this.methodsCondition = (methods != null ? methods : EMPTY_REQUEST_METHODS);
|
||||
this.paramsCondition = (params != null ? params : EMPTY_PARAMS);
|
||||
this.headersCondition = (headers != null ? headers : EMPTY_HEADERS);
|
||||
this.consumesCondition = (consumes != null ? consumes : EMPTY_CONSUMES);
|
||||
this.producesCondition = (produces != null ? produces : EMPTY_PRODUCES);
|
||||
this.customConditionHolder = new RequestConditionHolder(custom);
|
||||
}
|
||||
|
||||
@@ -427,7 +441,7 @@ public final class RequestMappingInfo implements RequestCondition<RequestMapping
|
||||
|
||||
private static class DefaultBuilder implements Builder {
|
||||
|
||||
private String[] paths = new String[0];
|
||||
private String[] paths;
|
||||
|
||||
private RequestMethod[] methods = new RequestMethod[0];
|
||||
|
||||
@@ -439,6 +453,10 @@ public final class RequestMappingInfo implements RequestCondition<RequestMapping
|
||||
|
||||
private String[] produces = new String[0];
|
||||
|
||||
private boolean hasContentType;
|
||||
|
||||
private boolean hasAccept;
|
||||
|
||||
@Nullable
|
||||
private String mappingName;
|
||||
|
||||
@@ -471,6 +489,12 @@ public final class RequestMappingInfo implements RequestCondition<RequestMapping
|
||||
|
||||
@Override
|
||||
public DefaultBuilder headers(String... headers) {
|
||||
for (String header : headers) {
|
||||
this.hasContentType = this.hasContentType ||
|
||||
header.contains("Content-Type") || header.contains("content-type");
|
||||
this.hasAccept = this.hasAccept ||
|
||||
header.contains("Accept") || header.contains("accept");
|
||||
}
|
||||
this.headers = headers;
|
||||
return this;
|
||||
}
|
||||
@@ -508,19 +532,26 @@ public final class RequestMappingInfo implements RequestCondition<RequestMapping
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public RequestMappingInfo build() {
|
||||
|
||||
PatternsRequestCondition patternsCondition = ObjectUtils.isEmpty(this.paths) ? null :
|
||||
new PatternsRequestCondition(
|
||||
this.paths, this.options.getUrlPathHelper(), this.options.getPathMatcher(),
|
||||
this.options.useSuffixPatternMatch(), this.options.useTrailingSlashMatch(),
|
||||
this.options.getFileExtensions());
|
||||
|
||||
ContentNegotiationManager manager = this.options.getContentNegotiationManager();
|
||||
|
||||
PatternsRequestCondition patternsCondition = new PatternsRequestCondition(
|
||||
this.paths, this.options.getUrlPathHelper(), this.options.getPathMatcher(),
|
||||
this.options.useSuffixPatternMatch(), this.options.useTrailingSlashMatch(),
|
||||
this.options.getFileExtensions());
|
||||
|
||||
return new RequestMappingInfo(this.mappingName, patternsCondition,
|
||||
new RequestMethodsRequestCondition(this.methods),
|
||||
new ParamsRequestCondition(this.params),
|
||||
new HeadersRequestCondition(this.headers),
|
||||
new ConsumesRequestCondition(this.consumes, this.headers),
|
||||
new ProducesRequestCondition(this.produces, this.headers, manager),
|
||||
ObjectUtils.isEmpty(this.methods) ?
|
||||
null : new RequestMethodsRequestCondition(this.methods),
|
||||
ObjectUtils.isEmpty(this.params) ?
|
||||
null : new ParamsRequestCondition(this.params),
|
||||
ObjectUtils.isEmpty(this.headers) ?
|
||||
null : new HeadersRequestCondition(this.headers),
|
||||
ObjectUtils.isEmpty(this.consumes) && !this.hasContentType ?
|
||||
null : new ConsumesRequestCondition(this.consumes, this.headers),
|
||||
ObjectUtils.isEmpty(this.produces) && !this.hasAccept ?
|
||||
null : new ProducesRequestCondition(this.produces, this.headers, manager),
|
||||
this.customCondition);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2020 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.
|
||||
@@ -17,7 +17,7 @@
|
||||
package org.springframework.web.servlet.mvc.condition;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Collections;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
@@ -48,8 +48,10 @@ public class PatternsRequestConditionTests {
|
||||
public void combineEmptySets() {
|
||||
PatternsRequestCondition c1 = new PatternsRequestCondition();
|
||||
PatternsRequestCondition c2 = new PatternsRequestCondition();
|
||||
PatternsRequestCondition c3 = c1.combine(c2);
|
||||
|
||||
assertThat(c1.combine(c2)).isEqualTo(new PatternsRequestCondition(""));
|
||||
assertThat(c3).isSameAs(c1);
|
||||
assertThat(c1.getPatterns()).isSameAs(c2.getPatterns()).containsExactly("");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -118,9 +120,8 @@ public class PatternsRequestConditionTests {
|
||||
|
||||
@Test // SPR-8410
|
||||
public void matchSuffixPatternUsingFileExtensions() {
|
||||
String[] patterns = new String[] {"/jobs/{jobName}"};
|
||||
List<String> extensions = Arrays.asList("json");
|
||||
PatternsRequestCondition condition = new PatternsRequestCondition(patterns, null, null, true, false, extensions);
|
||||
PatternsRequestCondition condition = new PatternsRequestCondition(
|
||||
new String[] {"/jobs/{jobName}"}, null, null, true, false, Collections.singletonList("json"));
|
||||
|
||||
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/jobs/my.job");
|
||||
PatternsRequestCondition match = condition.getMatchingCondition(request);
|
||||
@@ -165,9 +166,11 @@ public class PatternsRequestConditionTests {
|
||||
match = condition.getMatchingCondition(request);
|
||||
|
||||
assertThat(match).isNotNull();
|
||||
assertThat(match.getPatterns().iterator().next()).as("Trailing slash should be insensitive to useSuffixPatternMatch settings (SPR-6164, SPR-5636)").isEqualTo("/foo/");
|
||||
assertThat(match.getPatterns().iterator().next())
|
||||
.as("Trailing slash should be insensitive to useSuffixPatternMatch settings (SPR-6164, SPR-5636)")
|
||||
.isEqualTo("/foo/");
|
||||
|
||||
condition = new PatternsRequestCondition(new String[] {"/foo"}, null, null, false, false);
|
||||
condition = new PatternsRequestCondition(new String[] {"/foo"}, null, null, false);
|
||||
match = condition.getMatchingCondition(request);
|
||||
|
||||
assertThat(match).isNull();
|
||||
@@ -175,8 +178,8 @@ public class PatternsRequestConditionTests {
|
||||
|
||||
@Test
|
||||
public void matchPatternContainsExtension() {
|
||||
PatternsRequestCondition condition = new PatternsRequestCondition("/foo.jpg");
|
||||
PatternsRequestCondition match = condition.getMatchingCondition(new MockHttpServletRequest("GET", "/foo.html"));
|
||||
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/foo.html");
|
||||
PatternsRequestCondition match = new PatternsRequestCondition("/foo.jpg").getMatchingCondition(request);
|
||||
|
||||
assertThat(match).isNull();
|
||||
}
|
||||
@@ -184,12 +187,10 @@ public class PatternsRequestConditionTests {
|
||||
@Test // gh-22543
|
||||
public void matchWithEmptyPatterns() {
|
||||
PatternsRequestCondition condition = new PatternsRequestCondition();
|
||||
assertThat(condition).isEqualTo(new PatternsRequestCondition(""));
|
||||
assertThat(condition.getMatchingCondition(new MockHttpServletRequest("GET", ""))).isNotNull();
|
||||
assertThat(condition.getMatchingCondition(new MockHttpServletRequest("GET", "/anything"))).isNull();
|
||||
|
||||
condition = condition.combine(new PatternsRequestCondition());
|
||||
assertThat(condition).isEqualTo(new PatternsRequestCondition(""));
|
||||
assertThat(condition.getMatchingCondition(new MockHttpServletRequest("GET", ""))).isNotNull();
|
||||
assertThat(condition.getMatchingCondition(new MockHttpServletRequest("GET", "/anything"))).isNull();
|
||||
}
|
||||
@@ -211,7 +212,7 @@ public class PatternsRequestConditionTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void compareNumberOfMatchingPatterns() throws Exception {
|
||||
public void compareNumberOfMatchingPatterns() {
|
||||
HttpServletRequest request = new MockHttpServletRequest("GET", "/foo.html");
|
||||
|
||||
PatternsRequestCondition c1 = new PatternsRequestCondition("/foo", "*.jpeg");
|
||||
|
||||
@@ -44,16 +44,33 @@ public class RequestMappingInfoTests {
|
||||
|
||||
@Test
|
||||
public void createEmpty() {
|
||||
|
||||
RequestMappingInfo info = paths().build();
|
||||
|
||||
// gh-22543
|
||||
assertThat(info.getPatternsCondition().getPatterns()).isEqualTo(Collections.singleton(""));
|
||||
assertThat(info.getMethodsCondition().getMethods().size()).isEqualTo(0);
|
||||
assertThat(info.getConsumesCondition().isEmpty()).isEqualTo(true);
|
||||
assertThat(info.getProducesCondition().isEmpty()).isEqualTo(true);
|
||||
assertThat(info.getParamsCondition()).isNotNull();
|
||||
assertThat(info.getHeadersCondition()).isNotNull();
|
||||
assertThat(info.getConsumesCondition().isEmpty()).isEqualTo(true);
|
||||
assertThat(info.getProducesCondition().isEmpty()).isEqualTo(true);
|
||||
assertThat(info.getCustomCondition()).isNull();
|
||||
|
||||
RequestMappingInfo anotherInfo = paths().build();
|
||||
assertThat(info.getPatternsCondition()).isSameAs(anotherInfo.getPatternsCondition());
|
||||
assertThat(info.getMethodsCondition()).isSameAs(anotherInfo.getMethodsCondition());
|
||||
assertThat(info.getParamsCondition()).isSameAs(anotherInfo.getParamsCondition());
|
||||
assertThat(info.getHeadersCondition()).isSameAs(anotherInfo.getHeadersCondition());
|
||||
assertThat(info.getConsumesCondition()).isSameAs(anotherInfo.getConsumesCondition());
|
||||
assertThat(info.getProducesCondition()).isSameAs(anotherInfo.getProducesCondition());
|
||||
|
||||
RequestMappingInfo result = info.combine(anotherInfo);
|
||||
assertThat(info.getPatternsCondition()).isSameAs(result.getPatternsCondition());
|
||||
assertThat(info.getMethodsCondition()).isSameAs(result.getMethodsCondition());
|
||||
assertThat(info.getParamsCondition()).isSameAs(result.getParamsCondition());
|
||||
assertThat(info.getHeadersCondition()).isSameAs(result.getHeadersCondition());
|
||||
assertThat(info.getConsumesCondition()).isSameAs(result.getConsumesCondition());
|
||||
assertThat(info.getProducesCondition()).isSameAs(result.getProducesCondition());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user