DATAREST-292 - Fixed application of configured base URI.

Major overhaul of mapping detection in RepositoryRestHandlerMapping. We now correctly map URIs if a base URI is configured via RepositoryRestConfiguration.
This commit is contained in:
Oliver Gierke
2014-04-23 17:56:28 +02:00
parent eb3d073714
commit 45ef259826
4 changed files with 75 additions and 19 deletions

View File

@@ -31,7 +31,7 @@ import org.springframework.util.Assert;
@SuppressWarnings("deprecation")
public class RepositoryRestConfiguration {
private URI baseUri = null;
private URI baseUri = URI.create("");
private int defaultPageSize = 20;
private int maxPageSize = 1000;
private String pageParamName = "page";

View File

@@ -31,8 +31,11 @@ import org.springframework.data.rest.webmvc.support.JpaHelper;
import org.springframework.http.MediaType;
import org.springframework.orm.jpa.support.OpenEntityManagerInViewInterceptor;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
import org.springframework.web.util.UriComponents;
import org.springframework.web.util.UriComponentsBuilder;
/**
* {@link RequestMappingHandlerMapping} implementation that will only find a handler method if a
@@ -111,24 +114,28 @@ public class RepositoryRestHandlerMapping extends RequestMappingHandlerMapping {
HttpServletRequest request = new DefaultAcceptTypeHttpServletRequest(origRequest, acceptType);
String requestUri = lookupPath;
if (requestUri.startsWith("/")) {
requestUri = requestUri.substring(1);
}
if (!hasText(requestUri)) {
if (!hasText(lookupPath)) {
return super.lookupHandlerMethod(lookupPath, request);
}
String[] parts = requestUri.split("/");
// Strip base URI
UriComponents components = UriComponentsBuilder.fromPath(lookupPath).build();
List<String> segments = components.getPathSegments();
String baseUri = config.getBaseUri().toString();
int repositoryIndex = !segments.isEmpty() && segments.get(0).equals(baseUri) ? 1 : 0;
segments = segments.subList(repositoryIndex, segments.size());
if (parts.length == 0) {
// Root request
return super.lookupHandlerMethod(lookupPath, request);
String uri = "/".concat(StringUtils.collectionToDelimitedString(segments, "/"));
request = new DefaultAcceptTypeHttpServletRequest(origRequest, acceptType, uri);
// Root request
if (uri.equals("/")) {
return super.lookupHandlerMethod(uri, request);
}
if (mappings.exportsTopLevelResourceFor(parts[0])) {
return super.lookupHandlerMethod(lookupPath, request);
if (mappings.exportsTopLevelResourceFor(segments.get(0))) {
return super.lookupHandlerMethod(uri, request);
}
return null;
@@ -159,10 +166,16 @@ public class RepositoryRestHandlerMapping extends RequestMappingHandlerMapping {
private static class DefaultAcceptTypeHttpServletRequest extends HttpServletRequestWrapper {
private final String defaultAcceptType;
private final String requestUri;
private DefaultAcceptTypeHttpServletRequest(HttpServletRequest request, String defaultAcceptType) {
this(request, defaultAcceptType, null);
}
private DefaultAcceptTypeHttpServletRequest(HttpServletRequest request, String defaultAcceptType, String requestUri) {
super(request);
this.defaultAcceptType = defaultAcceptType;
this.requestUri = requestUri;
}
@Override
@@ -174,5 +187,14 @@ public class RepositoryRestHandlerMapping extends RequestMappingHandlerMapping {
return super.getHeader(name);
}
}
/*
* (non-Javadoc)
* @see javax.servlet.http.HttpServletRequestWrapper#getRequestURI()
*/
@Override
public String getRequestURI() {
return requestUri != null ? requestUri : super.getRequestURI();
}
}
}

View File

@@ -19,10 +19,9 @@ import java.net.URI;
import org.springframework.data.mapping.PersistentProperty;
import org.springframework.data.rest.core.mapping.ResourceMetadata;
import org.springframework.data.rest.webmvc.RepositoryController;
import org.springframework.hateoas.Link;
import org.springframework.hateoas.core.LinkBuilderSupport;
import org.springframework.hateoas.mvc.ControllerLinkBuilder;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
import org.springframework.web.util.UriComponentsBuilder;
public class RepositoryLinkBuilder extends LinkBuilderSupport<RepositoryLinkBuilder> {
@@ -41,9 +40,8 @@ public class RepositoryLinkBuilder extends LinkBuilderSupport<RepositoryLinkBuil
private static UriComponentsBuilder prepareBuilder(URI baseUri, ResourceMetadata metadata) {
UriComponentsBuilder builder = baseUri != null ? UriComponentsBuilder.fromUri(baseUri) : ControllerLinkBuilder
.linkTo(RepositoryController.class).toUriComponentsBuilder();
return builder.path(metadata.getPath().toString());
ServletUriComponentsBuilder builder = ServletUriComponentsBuilder.fromCurrentServletMapping();
return builder.path(baseUri.toString()).path(metadata.getPath().toString());
}
@Override

View File

@@ -20,6 +20,7 @@ import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
import java.lang.reflect.Method;
import java.net.URI;
import org.junit.Before;
import org.junit.Test;
@@ -51,7 +52,7 @@ public class RepositoryRestHandlerMappingUnitTests {
RepositoryRestConfiguration configuration;
RepositoryRestHandlerMapping handlerMapping;
MockHttpServletRequest mockRequest;
Method listEntitiesMethod;
Method listEntitiesMethod, rootHandlerMethod;
@Before
public void setUp() throws Exception {
@@ -66,6 +67,7 @@ public class RepositoryRestHandlerMappingUnitTests {
listEntitiesMethod = RepositoryEntityController.class.getMethod("getCollectionResource",
RootResourceInformation.class, Pageable.class, Sort.class, PersistentEntityResourceAssembler.class);
rootHandlerMethod = RepositoryController.class.getMethod("listRepositories");
}
@Test(expected = IllegalArgumentException.class)
@@ -100,4 +102,38 @@ public class RepositoryRestHandlerMappingUnitTests {
assertThat(method, is(notNullValue()));
assertThat(method.getMethod(), is(listEntitiesMethod));
}
/**
* @see DATAREST-292
*/
@Test
public void returnsRepositoryHandlerMethodWithBaseUriConfigured() throws Exception {
when(mappings.exportsTopLevelResourceFor("people")).thenReturn(true);
mockRequest = new MockHttpServletRequest("GET", "/base/people");
configuration.setBaseUri(URI.create("base"));
HandlerMethod method = handlerMapping.lookupHandlerMethod("/base/people", mockRequest);
assertThat(method, is(notNullValue()));
assertThat(method.getMethod(), is(listEntitiesMethod));
}
/**
* @see DATAREST-292
*/
@Test
public void returnsRootHandlerMethodWithBaseUriConfigured() throws Exception {
when(mappings.exportsTopLevelResourceFor("people")).thenReturn(true);
mockRequest = new MockHttpServletRequest("GET", "/base");
configuration.setBaseUri(URI.create("base"));
HandlerMethod method = handlerMapping.lookupHandlerMethod("/base", mockRequest);
assertThat(method, is(notNullValue()));
assertThat(method.getMethod(), is(rootHandlerMethod));
}
}