Merge branch '2.0.x'

This commit is contained in:
Madhura Bhave
2018-08-16 15:45:20 -07:00
11 changed files with 345 additions and 18 deletions

View File

@@ -23,6 +23,7 @@ import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@@ -49,6 +50,8 @@ import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.servlet.HandlerMapping;
import org.springframework.web.servlet.handler.MatchableHandlerMapping;
import org.springframework.web.servlet.handler.RequestMatchResult;
import org.springframework.web.servlet.mvc.condition.ConsumesRequestCondition;
import org.springframework.web.servlet.mvc.condition.PatternsRequestCondition;
import org.springframework.web.servlet.mvc.condition.ProducesRequestCondition;
@@ -66,7 +69,8 @@ import org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMappi
* @since 2.0.0
*/
public abstract class AbstractWebMvcEndpointHandlerMapping
extends RequestMappingInfoHandlerMapping implements InitializingBean {
extends RequestMappingInfoHandlerMapping
implements InitializingBean, MatchableHandlerMapping {
private final EndpointMapping endpointMapping;
@@ -82,6 +86,8 @@ public abstract class AbstractWebMvcEndpointHandlerMapping
private final Method handleMethod = ReflectionUtils.findMethod(OperationHandler.class,
"handle", HttpServletRequest.class, Map.class);
private static final RequestMappingInfo.BuilderConfiguration builderConfig = getBuilderConfig();
/**
* Creates a new {@code WebEndpointHandlerMapping} that provides mappings for the
* operations of the given {@code webEndpoints}.
@@ -125,6 +131,29 @@ public abstract class AbstractWebMvcEndpointHandlerMapping
}
}
@Override
public RequestMatchResult match(HttpServletRequest request, String pattern) {
RequestMappingInfo info = RequestMappingInfo.paths(pattern).options(builderConfig)
.build();
RequestMappingInfo matchingInfo = info.getMatchingCondition(request);
if (matchingInfo == null) {
return null;
}
Set<String> patterns = matchingInfo.getPatternsCondition().getPatterns();
String lookupPath = getUrlPathHelper().getLookupPathForRequest(request);
return new RequestMatchResult(patterns.iterator().next(), lookupPath,
getPathMatcher());
}
private static RequestMappingInfo.BuilderConfiguration getBuilderConfig() {
RequestMappingInfo.BuilderConfiguration config = new RequestMappingInfo.BuilderConfiguration();
config.setUrlPathHelper(null);
config.setPathMatcher(null);
config.setSuffixPatternMatch(false);
config.setTrailingSlashMatch(true);
return config;
}
private void registerMappingForOperation(ExposableWebEndpoint endpoint,
WebOperation operation) {
OperationInvoker invoker = operation::invoke;
@@ -176,7 +205,9 @@ public abstract class AbstractWebMvcEndpointHandlerMapping
private PatternsRequestCondition patternsRequestConditionForPattern(String path) {
String[] patterns = new String[] { this.endpointMapping.createSubPath(path) };
return new PatternsRequestCondition(patterns, null, null, false, true);
return new PatternsRequestCondition(patterns, builderConfig.getUrlPathHelper(),
builderConfig.getPathMatcher(), builderConfig.useSuffixPatternMatch(),
builderConfig.useTrailingSlashMatch());
}
@Override

View File

@@ -46,6 +46,7 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContext;
@@ -53,6 +54,7 @@ import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestWrapper;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.filter.OncePerRequestFilter;
import org.springframework.web.servlet.handler.RequestMatchResult;
import static org.assertj.core.api.Assertions.assertThat;
@@ -104,6 +106,27 @@ public class MvcWebEndpointIntegrationTests extends
});
}
@Test
public void matchWhenRequestHasTrailingSlashShouldNotBeNull() {
assertThat(getMatchResult("/spring/")).isNotNull();
}
@Test
public void matchWhenRequestHasSuffixShouldBeNull() {
assertThat(getMatchResult("/spring.do")).isNull();
}
private RequestMatchResult getMatchResult(String s) {
MockHttpServletRequest request = new MockHttpServletRequest();
request.setServletPath(s);
AnnotationConfigServletWebServerApplicationContext context = createApplicationContext();
context.register(TestEndpointConfiguration.class);
context.refresh();
WebMvcEndpointHandlerMapping bean = context
.getBean(WebMvcEndpointHandlerMapping.class);
return bean.match(request, "/spring");
}
@Override
protected int getPort(AnnotationConfigServletWebServerApplicationContext context) {
return context.getWebServer().getPort();