diff --git a/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/config/RepositoryRestConfiguration.java b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/config/RepositoryRestConfiguration.java index bc84a664c..5ce09c895 100644 --- a/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/config/RepositoryRestConfiguration.java +++ b/spring-data-rest-core/src/main/java/org/springframework/data/rest/core/config/RepositoryRestConfiguration.java @@ -51,7 +51,7 @@ @SuppressWarnings("deprecation") public class RepositoryRestConfiguration { - private static final URI NO_URI = URI.create(""); + static final URI NO_URI = URI.create(""); private URI baseUri = NO_URI; private URI basePath = NO_URI; @@ -109,7 +109,9 @@ public RepositoryRestConfiguration(ProjectionDefinitionConfiguration projectionC * The base URI against which the exporter should calculate its links. * * @return The base URI. + * @deprecated use {@link #getBasePath()} instead. */ + @Deprecated public URI getBaseUri() { return basePath != NO_URI ? basePath : baseUri; } diff --git a/spring-data-rest-tests/spring-data-rest-tests-mongodb/src/test/java/org/springframework/data/rest/webmvc/RepositoryRestHandlerMappingIntegrationTests.java b/spring-data-rest-tests/spring-data-rest-tests-mongodb/src/test/java/org/springframework/data/rest/webmvc/RepositoryRestHandlerMappingIntegrationTests.java index 2f4ec4bcd..c716d4a30 100755 --- a/spring-data-rest-tests/spring-data-rest-tests-mongodb/src/test/java/org/springframework/data/rest/webmvc/RepositoryRestHandlerMappingIntegrationTests.java +++ b/spring-data-rest-tests/spring-data-rest-tests-mongodb/src/test/java/org/springframework/data/rest/webmvc/RepositoryRestHandlerMappingIntegrationTests.java @@ -21,11 +21,11 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.rest.tests.AbstractControllerIntegrationTests; import org.springframework.data.rest.tests.mongodb.MongoDbRepositoryConfig; -import org.springframework.data.rest.webmvc.support.DelegatingHandlerMapping; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.test.context.ContextConfiguration; import org.springframework.web.method.HandlerMethod; import org.springframework.web.servlet.HandlerExecutionChain; +import org.springframework.web.servlet.HandlerMapping; /** * Integration tests for {@link BasePathAwareHandlerMapping}. @@ -36,7 +36,7 @@ @ContextConfiguration(classes = MongoDbRepositoryConfig.class) public class RepositoryRestHandlerMappingIntegrationTests extends AbstractControllerIntegrationTests { - @Autowired DelegatingHandlerMapping mapping; + @Autowired HandlerMapping mapping; @Test // DATAREST-617 public void usesMethodsWithoutProducesClauseForGeneralJsonRequests() throws Exception { diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/BasePathAwareHandlerMapping.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/BasePathAwareHandlerMapping.java index 15a795b7f..6061e2cd3 100644 --- a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/BasePathAwareHandlerMapping.java +++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/BasePathAwareHandlerMapping.java @@ -15,35 +15,17 @@ */ package org.springframework.data.rest.webmvc; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.UnsupportedEncodingException; import java.lang.reflect.Method; -import java.net.URI; -import java.security.Principal; import java.util.ArrayList; -import java.util.Collection; import java.util.Collections; import java.util.Enumeration; +import java.util.HashMap; import java.util.List; -import java.util.Locale; import java.util.Map; -import java.util.Set; - -import javax.servlet.AsyncContext; -import javax.servlet.DispatcherType; -import javax.servlet.RequestDispatcher; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.ServletInputStream; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.Cookie; +import java.util.function.Predicate; + import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; -import javax.servlet.http.Part; import org.springframework.data.rest.core.config.RepositoryRestConfiguration; import org.springframework.data.util.ProxyUtils; @@ -52,11 +34,9 @@ import org.springframework.util.Assert; import org.springframework.util.StringUtils; import org.springframework.web.method.HandlerMethod; -import org.springframework.web.servlet.mvc.condition.PatternsRequestCondition; import org.springframework.web.servlet.mvc.condition.ProducesRequestCondition; import org.springframework.web.servlet.mvc.method.RequestMappingInfo; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; -import org.springframework.web.util.UrlPathHelper; /** * A {@link RequestMappingHandlerMapping} that augments the request mappings @@ -65,12 +45,8 @@ */ public class BasePathAwareHandlerMapping extends RequestMappingHandlerMapping { - private static final UrlPathHelper URL_PATH_HELPER = new UrlPathHelper(); - private final RepositoryRestConfiguration configuration; - private String prefix; - /** * Creates a new {@link BasePathAwareHandlerMapping} using the given {@link RepositoryRestConfiguration}. * @@ -79,7 +55,18 @@ public class BasePathAwareHandlerMapping extends RequestMappingHandlerMapping { public BasePathAwareHandlerMapping(RepositoryRestConfiguration configuration) { Assert.notNull(configuration, "RepositoryRestConfiguration must not be null!"); + this.configuration = configuration; + + String baseUri = configuration.getBasePath().toString(); + + if (StringUtils.hasText(baseUri)) { + + Map>> prefixes = new HashMap<>(); + prefixes.put(baseUri, it -> true); + + this.setPathPrefixes(prefixes); + } } /* @@ -134,34 +121,12 @@ protected RequestMappingInfo getMappingForMethod(Method method, Class handler return null; } - PatternsRequestCondition patternsCondition = customize(info.getPatternsCondition(), prefix); ProducesRequestCondition producesCondition = customize(info.getProducesCondition()); - return new RequestMappingInfo(patternsCondition, info.getMethodsCondition(), info.getParamsCondition(), + return new RequestMappingInfo(info.getPatternsCondition(), info.getMethodsCondition(), info.getParamsCondition(), info.getHeadersCondition(), info.getConsumesCondition(), producesCondition, info.getCustomCondition()); } - /** - * Customize the given {@link PatternsRequestCondition} and prefix. - * - * @param condition will never be {@literal null}. - * @param prefix will never be {@literal null}. - * @return - */ - protected PatternsRequestCondition customize(PatternsRequestCondition condition, String prefix) { - - Set patterns = condition.getPatterns(); - String[] augmentedPatterns = new String[patterns.size()]; - int count = 0; - - for (String pattern : patterns) { - augmentedPatterns[count++] = prefix.concat(pattern); - } - - return new PatternsRequestCondition(augmentedPatterns, getUrlPathHelper(), getPathMatcher(), - useSuffixPatternMatch(), useTrailingSlashMatch(), getFileExtensions()); - } - /** * Customize the given {@link ProducesRequestCondition}. Default implementation returns the condition as is. * @@ -184,391 +149,6 @@ protected boolean isHandler(Class beanType) { return type.isAnnotationPresent(BasePathAwareController.class); } - /* - * (non-Javadoc) - * @see org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping#afterPropertiesSet() - */ - @Override - public void afterPropertiesSet() { - - URI baseUri = configuration.getBaseUri(); - - if (baseUri.isAbsolute()) { - HttpServletRequest request = new UriAwareHttpServletRequest(getServletContext(), baseUri); - this.prefix = URL_PATH_HELPER.getPathWithinApplication(request); - } else { - this.prefix = baseUri.toString(); - } - - super.afterPropertiesSet(); - } - - private static class UriAwareHttpServletRequest implements HttpServletRequest { - - private final ServletContext context; - private final String path; - - /** - * @param context - * @param uri - */ - public UriAwareHttpServletRequest(ServletContext context, URI uri) { - this.context = context; - this.path = uri.getPath(); - } - - /* - * (non-Javadoc) - * @see javax.servlet.ServletRequest#getAttribute(java.lang.String) - */ - @Override - public Object getAttribute(String name) { - return null; - } - - @Override - public Enumeration getAttributeNames() { - throw new UnsupportedOperationException(); - } - - /* - * (non-Javadoc) - * @see javax.servlet.ServletRequest#getCharacterEncoding() - */ - @Override - public String getCharacterEncoding() { - return null; - } - - @Override - public void setCharacterEncoding(String env) throws UnsupportedEncodingException { - throw new UnsupportedOperationException(); - } - - @Override - public int getContentLength() { - throw new UnsupportedOperationException(); - } - - @Override - public String getContentType() { - throw new UnsupportedOperationException(); - } - - @Override - public ServletInputStream getInputStream() throws IOException { - throw new UnsupportedOperationException(); - } - - @Override - public String getParameter(String name) { - throw new UnsupportedOperationException(); - } - - @Override - public Enumeration getParameterNames() { - throw new UnsupportedOperationException(); - } - - @Override - public String[] getParameterValues(String name) { - throw new UnsupportedOperationException(); - } - - @Override - public Map getParameterMap() { - throw new UnsupportedOperationException(); - } - - @Override - public String getProtocol() { - throw new UnsupportedOperationException(); - } - - @Override - public String getScheme() { - throw new UnsupportedOperationException(); - } - - @Override - public String getServerName() { - throw new UnsupportedOperationException(); - } - - @Override - public int getServerPort() { - throw new UnsupportedOperationException(); - } - - @Override - public BufferedReader getReader() throws IOException { - throw new UnsupportedOperationException(); - } - - @Override - public String getRemoteAddr() { - throw new UnsupportedOperationException(); - } - - @Override - public String getRemoteHost() { - throw new UnsupportedOperationException(); - } - - @Override - public void setAttribute(String name, Object o) { - throw new UnsupportedOperationException(); - } - - @Override - public void removeAttribute(String name) { - throw new UnsupportedOperationException(); - } - - @Override - public Locale getLocale() { - throw new UnsupportedOperationException(); - } - - @Override - public Enumeration getLocales() { - throw new UnsupportedOperationException(); - } - - @Override - public boolean isSecure() { - throw new UnsupportedOperationException(); - } - - @Override - public RequestDispatcher getRequestDispatcher(String path) { - throw new UnsupportedOperationException(); - } - - @Override - public String getRealPath(String path) { - throw new UnsupportedOperationException(); - } - - @Override - public int getRemotePort() { - throw new UnsupportedOperationException(); - } - - @Override - public String getLocalName() { - throw new UnsupportedOperationException(); - } - - @Override - public String getLocalAddr() { - throw new UnsupportedOperationException(); - } - - @Override - public int getLocalPort() { - throw new UnsupportedOperationException(); - } - - /* - * (non-Javadoc) - * @see javax.servlet.ServletRequest#getServletContext() - */ - @Override - public ServletContext getServletContext() { - return context; - } - - @Override - public AsyncContext startAsync() throws IllegalStateException { - throw new UnsupportedOperationException(); - } - - @Override - public AsyncContext startAsync(ServletRequest servletRequest, ServletResponse servletResponse) - throws IllegalStateException { - throw new UnsupportedOperationException(); - } - - @Override - public boolean isAsyncStarted() { - throw new UnsupportedOperationException(); - } - - @Override - public boolean isAsyncSupported() { - throw new UnsupportedOperationException(); - } - - @Override - public AsyncContext getAsyncContext() { - throw new UnsupportedOperationException(); - } - - @Override - public DispatcherType getDispatcherType() { - throw new UnsupportedOperationException(); - } - - @Override - public String getAuthType() { - throw new UnsupportedOperationException(); - } - - @Override - public Cookie[] getCookies() { - throw new UnsupportedOperationException(); - } - - @Override - public long getDateHeader(String name) { - throw new UnsupportedOperationException(); - } - - @Override - public String getHeader(String name) { - throw new UnsupportedOperationException(); - } - - @Override - public Enumeration getHeaders(String name) { - throw new UnsupportedOperationException(); - } - - @Override - public Enumeration getHeaderNames() { - throw new UnsupportedOperationException(); - } - - @Override - public int getIntHeader(String name) { - throw new UnsupportedOperationException(); - } - - @Override - public String getMethod() { - throw new UnsupportedOperationException(); - } - - @Override - public String getPathInfo() { - throw new UnsupportedOperationException(); - } - - @Override - public String getPathTranslated() { - throw new UnsupportedOperationException(); - } - - /* - * (non-Javadoc) - * @see javax.servlet.http.HttpServletRequest#getContextPath() - */ - @Override - public String getContextPath() { - return context.getContextPath(); - } - - @Override - public String getQueryString() { - throw new UnsupportedOperationException(); - } - - @Override - public String getRemoteUser() { - throw new UnsupportedOperationException(); - } - - @Override - public boolean isUserInRole(String role) { - throw new UnsupportedOperationException(); - } - - @Override - public Principal getUserPrincipal() { - throw new UnsupportedOperationException(); - } - - @Override - public String getRequestedSessionId() { - throw new UnsupportedOperationException(); - } - - /* - * (non-Javadoc) - * @see javax.servlet.http.HttpServletRequest#getRequestURI() - */ - @Override - public String getRequestURI() { - return path; - } - - @Override - public StringBuffer getRequestURL() { - throw new UnsupportedOperationException(); - } - - @Override - public String getServletPath() { - throw new UnsupportedOperationException(); - } - - @Override - public HttpSession getSession(boolean create) { - throw new UnsupportedOperationException(); - } - - @Override - public HttpSession getSession() { - throw new UnsupportedOperationException(); - } - - @Override - public boolean isRequestedSessionIdValid() { - throw new UnsupportedOperationException(); - } - - @Override - public boolean isRequestedSessionIdFromCookie() { - throw new UnsupportedOperationException(); - } - - @Override - public boolean isRequestedSessionIdFromURL() { - throw new UnsupportedOperationException(); - } - - @Override - public boolean isRequestedSessionIdFromUrl() { - throw new UnsupportedOperationException(); - } - - @Override - public boolean authenticate(HttpServletResponse response) throws IOException, ServletException { - throw new UnsupportedOperationException(); - } - - @Override - public void login(String username, String password) throws ServletException { - throw new UnsupportedOperationException(); - } - - @Override - public void logout() throws ServletException { - throw new UnsupportedOperationException(); - } - - @Override - public Collection getParts() throws IOException, ServletException { - throw new UnsupportedOperationException(); - } - - @Override - public Part getPart(String name) throws IOException, ServletException { - throw new UnsupportedOperationException(); - } - } - /** * {@link HttpServletRequest} that exposes the given media types for the {@code Accept} header. * @@ -610,11 +190,9 @@ public CustomAcceptHeaderHttpServletRequest(HttpServletRequest request, List getHeaders(String name) { - if (HttpHeaders.ACCEPT.equalsIgnoreCase(name) && acceptMediaTypes != null) { - return Collections.enumeration(acceptMediaTypeStrings); - } - - return super.getHeaders(name); + return HttpHeaders.ACCEPT.equalsIgnoreCase(name) && acceptMediaTypes != null // + ? Collections.enumeration(acceptMediaTypeStrings) // + : super.getHeaders(name); } } } diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/ProfileController.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/ProfileController.java index 31015b4ad..70e8adf92 100644 --- a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/ProfileController.java +++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/ProfileController.java @@ -118,7 +118,7 @@ HttpEntity> listAllFormsOfMetadata() { */ public static String getRootPath(RepositoryRestConfiguration configuration) { - BaseUri baseUri = new BaseUri(configuration.getBaseUri()); + BaseUri baseUri = new BaseUri(configuration.getBasePath()); return baseUri.getUriComponentsBuilder().path(ProfileController.PROFILE_ROOT_MAPPING).build().toString(); } diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositoryRestHandlerMapping.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositoryRestHandlerMapping.java index c54d36cd0..5d2a7aba6 100644 --- a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositoryRestHandlerMapping.java +++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositoryRestHandlerMapping.java @@ -19,7 +19,6 @@ import lombok.RequiredArgsConstructor; import java.util.Collections; -import java.util.HashSet; import java.util.LinkedHashSet; import java.util.List; import java.util.Optional; @@ -147,7 +146,7 @@ protected HandlerMethod lookupHandlerMethod(String lookupPath, HttpServletReques return null; } - String repositoryLookupPath = new BaseUri(configuration.getBaseUri()).getRepositoryLookupPath(lookupPath); + String repositoryLookupPath = new BaseUri(configuration.getBasePath()).getRepositoryLookupPath(lookupPath); // Repository root resource if (!StringUtils.hasText(repositoryLookupPath)) { @@ -210,7 +209,7 @@ protected ProducesRequestCondition customize(ProducesRequestCondition condition) return condition; } - HashSet mediaTypes = new LinkedHashSet(); + Set mediaTypes = new LinkedHashSet(); mediaTypes.add(configuration.getDefaultMediaType().toString()); mediaTypes.add(MediaType.APPLICATION_JSON_VALUE); @@ -224,7 +223,7 @@ protected ProducesRequestCondition customize(ProducesRequestCondition condition) protected CorsConfiguration getCorsConfiguration(Object handler, HttpServletRequest request) { String lookupPath = getUrlPathHelper().getLookupPathForRequest(request); - String repositoryLookupPath = new BaseUri(configuration.getBaseUri()).getRepositoryLookupPath(lookupPath); + String repositoryLookupPath = new BaseUri(configuration.getBasePath()).getRepositoryLookupPath(lookupPath); CorsConfiguration corsConfiguration = super.getCorsConfiguration(handler, request); return repositories.filter(it -> StringUtils.hasText(repositoryLookupPath))// diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/support/DelegatingHandlerMapping.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/config/DelegatingHandlerMapping.java similarity index 86% rename from spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/support/DelegatingHandlerMapping.java rename to spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/config/DelegatingHandlerMapping.java index 2156297d1..7ed37d650 100644 --- a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/support/DelegatingHandlerMapping.java +++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/config/DelegatingHandlerMapping.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.data.rest.webmvc.support; +package org.springframework.data.rest.webmvc.config; import lombok.Getter; import lombok.NonNull; @@ -31,6 +31,7 @@ import org.springframework.web.bind.UnsatisfiedServletRequestParameterException; import org.springframework.web.servlet.HandlerExecutionChain; import org.springframework.web.servlet.HandlerMapping; +import org.springframework.web.servlet.handler.AbstractHandlerMapping; import org.springframework.web.servlet.handler.MatchableHandlerMapping; import org.springframework.web.servlet.handler.RequestMatchResult; import org.springframework.web.util.pattern.PathPatternParser; @@ -42,7 +43,7 @@ * @author Oliver Gierke * @soundtrack Benny Greb - Stabila (Moving Parts) */ -public class DelegatingHandlerMapping implements HandlerMapping, Ordered, MatchableHandlerMapping { +class DelegatingHandlerMapping extends AbstractHandlerMapping implements MatchableHandlerMapping { private final @Getter List delegates; @@ -58,6 +59,17 @@ public DelegatingHandlerMapping(List delegates) { this.delegates = delegates; } + @Override + public void setPatternParser(PathPatternParser parser) { + + super.setPatternParser(parser); + + delegates.stream() // + .filter(AbstractHandlerMapping.class::isInstance) // + .map(AbstractHandlerMapping.class::cast) // + .forEach(it -> it.setPatternParser(parser)); + } + /* * (non-Javadoc) * @see org.springframework.core.Ordered#getOrder() @@ -69,10 +81,10 @@ public int getOrder() { /* * (non-Javadoc) - * @see org.springframework.web.servlet.HandlerMapping#getHandler(javax.servlet.http.HttpServletRequest) + * @see org.springframework.web.servlet.handler.AbstractHandlerMapping#getHandlerInternal(javax.servlet.http.HttpServletRequest) */ @Override - public HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception { + protected Object getHandlerInternal(HttpServletRequest request) throws Exception { return HandlerSelectionResult.from(request, delegates).resultOrException(); } @@ -90,14 +102,6 @@ public RequestMatchResult match(HttpServletRequest request, String pattern) { } } - /* - * (non-Javadoc) - * @see org.springframework.web.servlet.handler.MatchableHandlerMapping#getPatternParser() - */ - public PathPatternParser getPatternParser() { - return null; - } - @Value private static class HandlerSelectionResult { diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/config/RepositoryRestMvcConfiguration.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/config/RepositoryRestMvcConfiguration.java index 97842b16f..e9a694b0f 100644 --- a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/config/RepositoryRestMvcConfiguration.java +++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/config/RepositoryRestMvcConfiguration.java @@ -80,7 +80,15 @@ import org.springframework.data.rest.webmvc.mapping.LinkCollector; import org.springframework.data.rest.webmvc.spi.BackendIdConverter; import org.springframework.data.rest.webmvc.spi.BackendIdConverter.DefaultIdConverter; -import org.springframework.data.rest.webmvc.support.*; +import org.springframework.data.rest.webmvc.support.BackendIdHandlerMethodArgumentResolver; +import org.springframework.data.rest.webmvc.support.DefaultExcerptProjector; +import org.springframework.data.rest.webmvc.support.DomainClassResolver; +import org.springframework.data.rest.webmvc.support.ETagArgumentResolver; +import org.springframework.data.rest.webmvc.support.ExcerptProjector; +import org.springframework.data.rest.webmvc.support.HttpMethodHandlerMethodArgumentResolver; +import org.springframework.data.rest.webmvc.support.JpaHelper; +import org.springframework.data.rest.webmvc.support.PagingAndSortingTemplateVariables; +import org.springframework.data.rest.webmvc.support.RepositoryEntityLinks; import org.springframework.data.util.AnnotatedTypeScanner; import org.springframework.data.util.Lazy; import org.springframework.data.web.HateoasPageableHandlerMethodArgumentResolver; @@ -114,7 +122,9 @@ import org.springframework.web.method.support.HandlerMethodArgumentResolver; import org.springframework.web.servlet.HandlerExceptionResolver; import org.springframework.web.servlet.HandlerMapping; +import org.springframework.web.servlet.config.annotation.PathMatchConfigurer; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; +import org.springframework.web.servlet.handler.AbstractHandlerMapping; import org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter; import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice; @@ -297,7 +307,7 @@ public MetadataConfiguration metadataConfiguration() { @Bean public BaseUri baseUri() { - return new BaseUri(repositoryRestConfiguration().getBaseUri()); + return new BaseUri(repositoryRestConfiguration().getBasePath()); } /** @@ -530,7 +540,7 @@ public RequestMappingHandlerAdapter repositoryExporterHandlerAdapter() { * @return */ @Bean - public DelegatingHandlerMapping restHandlerMapping() { + public AbstractHandlerMapping restHandlerMapping() { Map corsConfigurations = repositoryRestConfiguration().getCorsRegistry() .getCorsConfigurations(); @@ -554,6 +564,15 @@ public DelegatingHandlerMapping restHandlerMapping() { return new DelegatingHandlerMapping(mappings); } + /* + * (non-Javadoc) + * @see org.springframework.web.servlet.config.annotation.WebMvcConfigurer#configurePathMatch(org.springframework.web.servlet.config.annotation.PathMatchConfigurer) + */ + @Override + public void configurePathMatch(PathMatchConfigurer configurer) { + restHandlerMapping().setPatternParser(configurer.getPatternParser()); + } + @Bean public RepositoryResourceMappings resourceMappings() { return new RepositoryResourceMappings(repositories(), persistentEntities(), repositoryRestConfiguration()); diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/support/RepositoryEntityLinks.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/support/RepositoryEntityLinks.java index fa2eae377..d43baf65b 100644 --- a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/support/RepositoryEntityLinks.java +++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/support/RepositoryEntityLinks.java @@ -86,7 +86,7 @@ public boolean supports(Class delimiter) { public LinkBuilder linkFor(Class type) { ResourceMetadata metadata = mappings.getMetadataFor(type); - return new RepositoryLinkBuilder(metadata, new BaseUri(config.getBaseUri())); + return new RepositoryLinkBuilder(metadata, new BaseUri(config.getBasePath())); } /* diff --git a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/BasePathAwareHandlerMappingUnitTests.java b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/BasePathAwareHandlerMappingUnitTests.java index bbca84fda..9bb7cb59d 100644 --- a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/BasePathAwareHandlerMappingUnitTests.java +++ b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/BasePathAwareHandlerMappingUnitTests.java @@ -18,6 +18,9 @@ import static org.assertj.core.api.Assertions.*; import static org.mockito.Mockito.*; +import java.net.URI; + +import org.junit.Before; import org.junit.Test; import org.springframework.aop.framework.ProxyFactory; import org.springframework.aop.support.AopUtils; @@ -30,8 +33,16 @@ */ public class BasePathAwareHandlerMappingUnitTests { - RepositoryRestConfiguration configuration = mock(RepositoryRestConfiguration.class); - HandlerMappingStub mapping = new HandlerMappingStub(configuration); + HandlerMappingStub mapping; + + @Before + public void setUp() { + + RepositoryRestConfiguration configuration = mock(RepositoryRestConfiguration.class); + doReturn(URI.create("")).when(configuration).getBasePath(); + + mapping = new HandlerMappingStub(configuration); + } @Test // DATAREST-1132 public void detectsAnnotationsOnProxies() { diff --git a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/RepositoryRestHandlerMappingUnitTests.java b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/RepositoryRestHandlerMappingUnitTests.java index 207fc3066..afee80ba9 100755 --- a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/RepositoryRestHandlerMappingUnitTests.java +++ b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/RepositoryRestHandlerMappingUnitTests.java @@ -19,7 +19,9 @@ import static org.mockito.Mockito.*; import java.lang.reflect.Method; +import java.net.URI; import java.util.Collections; +import java.util.function.Supplier; import javax.servlet.http.HttpServletRequest; @@ -71,7 +73,7 @@ public class RepositoryRestHandlerMappingUnitTests { @Mock Repositories repositories; RepositoryRestConfiguration configuration; - HandlerMappingStub handlerMapping; + Supplier handlerMapping; MockHttpServletRequest mockRequest; Method listEntitiesMethod, rootHandlerMethod; @@ -81,8 +83,14 @@ public void setUp() throws Exception { configuration = new RepositoryRestConfiguration(new ProjectionDefinitionConfiguration(), new MetadataConfiguration(), mock(EnumTranslationConfiguration.class)); - handlerMapping = new HandlerMappingStub(mappings, configuration, repositories); - handlerMapping.setApplicationContext(CONTEXT); + handlerMapping = () -> { + + HandlerMappingStub mapping = new HandlerMappingStub(mappings, configuration, repositories); + mapping.setApplicationContext(CONTEXT); + mapping.afterPropertiesSet(); + + return mapping; + }; mockRequest = new MockHttpServletRequest(); @@ -103,9 +111,7 @@ public void rejectsNullConfiguration() { @Test // DATAREST-111 public void returnsNullForUriNotMapped() throws Exception { - - handlerMapping.afterPropertiesSet(); - assertThat(handlerMapping.getHandler(mockRequest)).isNull(); + assertThat(handlerMapping.get().getHandler(mockRequest)).isNull(); } @Test // DATAREST-111 @@ -114,8 +120,7 @@ public void looksUpRepositoryEntityControllerMethodCorrectly() throws Exception when(mappings.exportsTopLevelResourceFor("/people")).thenReturn(true); mockRequest = new MockHttpServletRequest("GET", "/people"); - handlerMapping.afterPropertiesSet(); - HandlerMethod method = handlerMapping.getHandlerInternal(mockRequest); + HandlerMethod method = handlerMapping.get().getHandlerInternal(mockRequest); assertThat(method).isNotNull(); assertThat(method.getMethod()).isEqualTo(listEntitiesMethod); @@ -128,9 +133,8 @@ public void returnsRepositoryHandlerMethodWithBaseUriConfigured() throws Excepti mockRequest = new MockHttpServletRequest("GET", "/base/people"); configuration.setBasePath("/base"); - handlerMapping.afterPropertiesSet(); - HandlerMethod method = handlerMapping.getHandlerInternal(mockRequest); + HandlerMethod method = handlerMapping.get().getHandlerInternal(mockRequest); assertThat(method).isNotNull(); assertThat(method.getMethod()).isEqualTo(listEntitiesMethod); @@ -142,9 +146,8 @@ public void returnsRootHandlerMethodWithBaseUriConfigured() throws Exception { mockRequest = new MockHttpServletRequest("GET", "/base"); configuration.setBasePath("/base"); - handlerMapping.afterPropertiesSet(); - HandlerMethod method = handlerMapping.getHandlerInternal(mockRequest); + HandlerMethod method = handlerMapping.get().getHandlerInternal(mockRequest); assertThat(method).isNotNull(); assertThat(method.getMethod()).isEqualTo(rootHandlerMethod); @@ -157,9 +160,8 @@ public void returnsRepositoryHandlerMethodForAbsoluteBaseUri() throws Exception mockRequest = new MockHttpServletRequest("GET", "/base/people/"); configuration.setBasePath("/base"); - handlerMapping.afterPropertiesSet(); - HandlerMethod method = handlerMapping.getHandlerInternal(mockRequest); + HandlerMethod method = handlerMapping.get().getHandlerInternal(mockRequest); assertThat(method).isNotNull(); assertThat(method.getMethod()).isEqualTo(listEntitiesMethod); @@ -173,9 +175,8 @@ public void returnsRepositoryHandlerMethodForAbsoluteBaseUriWithServletMapping() mockRequest.setServletPath("/base/people"); configuration.setBasePath("/base"); - handlerMapping.afterPropertiesSet(); - HandlerMethod method = handlerMapping.getHandlerInternal(mockRequest); + HandlerMethod method = handlerMapping.get().getHandlerInternal(mockRequest); assertThat(method).isNotNull(); assertThat(method.getMethod()).isEqualTo(listEntitiesMethod); @@ -189,7 +190,7 @@ public void refrainsFromMappingIfTheRequestDoesNotPointIntoAbsolutelyDefinedUriS configuration.setBasePath("/base"); - HandlerMethod method = handlerMapping.getHandlerInternal(mockRequest); + HandlerMethod method = handlerMapping.get().getHandlerInternal(mockRequest); assertThat(method).isNull(); } @@ -206,7 +207,7 @@ public void refrainsFromMappingWhenUrisDontMatch() throws Exception { configuration.setBasePath(baseUri); - HandlerMethod method = handlerMapping.getHandlerInternal(mockRequest); + HandlerMethod method = handlerMapping.get().getHandlerInternal(mockRequest); assertThat(method).isNull(); } @@ -218,7 +219,7 @@ public void rejectsUnexpandedUriTemplateWithNotFound() throws Exception { mockRequest = new MockHttpServletRequest("GET", "/people{?projection}"); - assertThat(handlerMapping.getHandler(mockRequest)).isNull(); + assertThat(handlerMapping.get().getHandler(mockRequest)).isNull(); } @Test // DATAREST-1019 @@ -233,7 +234,7 @@ public void resolvesCorsConfigurationFromRequestUri() { mockRequest = new MockHttpServletRequest("GET", uri); mockRequest.setServletPath(uri); - handlerMapping.getCorsConfiguration(uri, mockRequest); + handlerMapping.get().getCorsConfiguration(uri, mockRequest); verify(mappings).exportsTopLevelResourceFor("/people"); } @@ -253,7 +254,7 @@ public void stripsBaseUriForCorsConfigurationResolution() { mockRequest = new MockHttpServletRequest("GET", uri); mockRequest.setServletPath(uri); - handlerMapping.getCorsConfiguration(uri, mockRequest); + handlerMapping.get().getCorsConfiguration(uri, mockRequest); verify(mappings).exportsTopLevelResourceFor("/people"); } @@ -268,8 +269,10 @@ public void detectsAnnotationsOnProxies() { Class type = createProxy(new SomeController()); - HandlerMappingStub mapping = new HandlerMappingStub(mock(ResourceMappings.class), - mock(RepositoryRestConfiguration.class)); + RepositoryRestConfiguration configuration = mock(RepositoryRestConfiguration.class); + doReturn(URI.create("")).when(configuration).getBasePath(); + + HandlerMappingStub mapping = new HandlerMappingStub(mock(ResourceMappings.class), configuration); assertThat(mapping.isHandler(type)).isTrue(); } @@ -281,8 +284,7 @@ public void exposesEffectiveRepositoryLookupPathAsRequestAttribute() throws Exce MockHttpServletRequest mockRequest = new MockHttpServletRequest("GET", "/people/search/findByLastnameLike"); - handlerMapping.afterPropertiesSet(); - handlerMapping.getHandlerInternal(mockRequest); + handlerMapping.get().getHandlerInternal(mockRequest); assertThat(mockRequest.getAttribute(RepositoryRestHandlerMapping.EFFECTIVE_LOOKUP_PATH_ATTRIBUTE)) // .isInstanceOfSatisfying(PathPattern.class, it -> { @@ -299,9 +301,7 @@ public void handlesCorsPreflightRequestsProperly() throws Exception { request.addHeader(HttpHeaders.ORIGIN, "test case"); request.addHeader(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, "GET"); - handlerMapping.afterPropertiesSet(); - - assertThatCode(() -> handlerMapping.getHandlerInternal(request)).doesNotThrowAnyException(); + assertThatCode(() -> handlerMapping.get().getHandlerInternal(request)).doesNotThrowAnyException(); } private static Class createProxy(Object source) { diff --git a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/support/DelegatingHandlerMappingUnitTests.java b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/config/DelegatingHandlerMappingUnitTests.java similarity index 98% rename from spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/support/DelegatingHandlerMappingUnitTests.java rename to spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/config/DelegatingHandlerMappingUnitTests.java index 10850edf9..a7afbf481 100755 --- a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/support/DelegatingHandlerMappingUnitTests.java +++ b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/config/DelegatingHandlerMappingUnitTests.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.data.rest.webmvc.support; +package org.springframework.data.rest.webmvc.config; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.fail;