Introduce PathPatternParser for optimized path matching

This commit introduces a PathPatternParser which parses request pattern
strings into PathPattern objects which can then be used to fast
match incoming string paths. The parser and matching supports the syntax
as described in SPR-14544. The code is optimized around the common usages
of request patterns and is designed to create very little transient
garbage when matching.

Issue: SPR-14544
This commit is contained in:
Andy Clement
2016-10-11 15:14:08 -07:00
committed by Brian Clozel
parent 6f029392c7
commit f58ffad939
44 changed files with 3880 additions and 73 deletions

View File

@@ -74,7 +74,7 @@ public class SimpleUrlHandlerMappingTests {
testUrl("welcome.html", null, handlerMapping, null);
testUrl("/pathmatchingAA.html", mainController, handlerMapping, "pathmatchingAA.html");
testUrl("/pathmatchingA.html", null, handlerMapping, null);
testUrl("/administrator/pathmatching.html", mainController, handlerMapping, "pathmatching.html");
testUrl("/administrator/pathmatching.html", mainController, handlerMapping, "/administrator/pathmatching.html");
testUrl("/administrator/test/pathmatching.html", mainController, handlerMapping, "test/pathmatching.html");
testUrl("/administratort/pathmatching.html", null, handlerMapping, null);
testUrl("/administrator/another/bla.xml", mainController, handlerMapping, "/administrator/another/bla.xml");

View File

@@ -98,9 +98,9 @@ public class PatternsRequestConditionTests {
@Test
public void matchSortPatterns() throws Exception {
PatternsRequestCondition condition = new PatternsRequestCondition("/**", "/foo/bar", "/foo/*");
PatternsRequestCondition condition = new PatternsRequestCondition("/*/*", "/foo/bar", "/foo/*");
PatternsRequestCondition match = condition.getMatchingCondition(createExchange("/foo/bar"));
PatternsRequestCondition expected = new PatternsRequestCondition("/foo/bar", "/foo/*", "/**");
PatternsRequestCondition expected = new PatternsRequestCondition("/foo/bar", "/foo/*", "/*/*");
assertEquals(expected, match);
}

View File

@@ -33,7 +33,6 @@ import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.mock.http.server.reactive.test.MockServerHttpRequest;
import org.springframework.mock.http.server.reactive.test.MockServerHttpResponse;
import org.springframework.stereotype.Controller;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.PathMatcher;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.method.HandlerMethod;
@@ -41,6 +40,7 @@ import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.adapter.DefaultServerWebExchange;
import org.springframework.web.server.session.MockWebSessionManager;
import org.springframework.web.server.session.WebSessionManager;
import org.springframework.web.util.ParsingPathMatcher;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
@@ -158,7 +158,7 @@ public class HandlerMethodMappingTests {
private static class MyHandlerMethodMapping extends AbstractHandlerMethodMapping<String> {
private PathMatcher pathMatcher = new AntPathMatcher();
private PathMatcher pathMatcher = new ParsingPathMatcher();
@Override
protected boolean isHandler(Class<?> beanType) {

View File

@@ -1,23 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="mapping" class="org.springframework.web.reactive.handler.SimpleUrlHandlerMapping">
<property name="urlDecode" value="true" />
<property name="mappings">
<value>
welcome.html=mainController
/**/pathmatchingTest.html=mainController
/**/pathmatching??.html=mainController
/**/path??matching.html=mainController
/**/??path??matching.html=mainController
/**/*.jsp=mainController
/administrator/**/pathmatching.html=mainController
/administrator/**/testlast*=mainController
/*pathmatchingTest.html=mainController
/pathmatching??.html=mainController
/administrator/pathmatching.html=mainController
/administrator/*/pathmatching.html=mainController
/administrator/*/testlast*=mainController
/administrator/testing/longer/*=mainController
/??path??matching.html=mainController
/path??matching.html=mainController
/administrator/another/bla.xml=mainController
/administrator/testing/longer/**/**/**/**/**=mainController
/administrator/testing/longer2/**/**/bla/**=mainController
/*test*.jpeg=mainController
/*/test.jpeg=mainController
/outofpattern*yeah=mainController