diff --git a/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/method/RequestMappingInfoHandlerMapping.java b/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/method/RequestMappingInfoHandlerMapping.java index 14f9232ca11..640fed7edac 100644 --- a/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/method/RequestMappingInfoHandlerMapping.java +++ b/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/method/RequestMappingInfoHandlerMapping.java @@ -27,6 +27,7 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; +import java.util.StringTokenizer; import java.util.stream.Collectors; import org.springframework.http.HttpHeaders; @@ -35,7 +36,9 @@ import org.springframework.http.InvalidMediaTypeException; import org.springframework.http.MediaType; import org.springframework.http.server.reactive.ServerHttpRequest; import org.springframework.util.CollectionUtils; +import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; +import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.method.HandlerMethod; import org.springframework.web.reactive.HandlerMapping; @@ -45,7 +48,6 @@ import org.springframework.web.server.MethodNotAllowedException; import org.springframework.web.server.NotAcceptableStatusException; import org.springframework.web.server.ServerWebExchange; import org.springframework.web.server.UnsupportedMediaTypeStatusException; -import org.springframework.web.util.WebUtils; /** * Abstract base class for classes for which {@link RequestMappingInfo} defines @@ -156,12 +158,43 @@ public abstract class RequestMappingInfoHandlerMapping extends AbstractHandlerMe uriVariables.put(uriVar.getKey(), uriVarValue.substring(0, semicolonIndex)); } - MultiValueMap vars = WebUtils.parseMatrixVariables(matrixVariables); + MultiValueMap vars = parseMatrixVariables(matrixVariables); result.put(uriVar.getKey(), getPathHelper().decodeMatrixVariables(exchange, vars)); } return result; } + /** + * Parse the given string with matrix variables. An example string would look + * like this {@code "q1=a;q1=b;q2=a,b,c"}. The resulting map would contain + * keys {@code "q1"} and {@code "q2"} with values {@code ["a","b"]} and + * {@code ["a","b","c"]} respectively. + * @param matrixVariables the unparsed matrix variables string + * @return a map with matrix variable names and values (never {@code null}) + */ + private static MultiValueMap parseMatrixVariables(String matrixVariables) { + MultiValueMap result = new LinkedMultiValueMap<>(); + if (!StringUtils.hasText(matrixVariables)) { + return result; + } + StringTokenizer pairs = new StringTokenizer(matrixVariables, ";"); + while (pairs.hasMoreTokens()) { + String pair = pairs.nextToken(); + int index = pair.indexOf('='); + if (index != -1) { + String name = pair.substring(0, index); + String rawValue = pair.substring(index + 1); + for (String value : StringUtils.commaDelimitedListToStringArray(rawValue)) { + result.add(name, value); + } + } + else { + result.add(pair, ""); + } + } + return result; + } + /** * Iterate all RequestMappingInfos once again, look if any match by URL at * least and raise exceptions accordingly. diff --git a/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/method/annotation/RequestMappingHandlerMapping.java b/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/method/annotation/RequestMappingHandlerMapping.java index a5f23e986b7..c27350e7079 100644 --- a/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/method/annotation/RequestMappingHandlerMapping.java +++ b/spring-web-reactive/src/main/java/org/springframework/web/reactive/result/method/annotation/RequestMappingHandlerMapping.java @@ -25,12 +25,9 @@ import org.springframework.core.annotation.AnnotatedElementUtils; import org.springframework.stereotype.Controller; import org.springframework.util.Assert; import org.springframework.util.StringValueResolver; -import org.springframework.web.accept.ContentNegotiationManager; import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.reactive.accept.CompositeContentTypeResolver; import org.springframework.web.reactive.accept.CompositeContentTypeResolverBuilder; import org.springframework.web.reactive.accept.ContentTypeResolver; -import org.springframework.web.reactive.accept.HeaderContentTypeResolver; import org.springframework.web.reactive.result.condition.RequestCondition; import org.springframework.web.reactive.result.method.RequestMappingInfo; import org.springframework.web.reactive.result.method.RequestMappingInfoHandlerMapping; @@ -93,7 +90,7 @@ public class RequestMappingHandlerMapping extends RequestMappingInfoHandlerMappi } /** - * Set the {@link ContentNegotiationManager} to use to determine requested media types. + * Set the {@link ContentTypeResolver} to use to determine requested media types. * If not set, the default constructor is used. */ public void setContentTypeResolver(ContentTypeResolver contentTypeResolver) {