diff --git a/src/main/java/org/springframework/hateoas/core/AnnotationMappingDiscoverer.java b/src/main/java/org/springframework/hateoas/core/AnnotationMappingDiscoverer.java index b723877d..dfe3818c 100644 --- a/src/main/java/org/springframework/hateoas/core/AnnotationMappingDiscoverer.java +++ b/src/main/java/org/springframework/hateoas/core/AnnotationMappingDiscoverer.java @@ -109,7 +109,17 @@ public class AnnotationMappingDiscoverer implements MappingDiscoverer { return typeMapping; } - return typeMapping == null || "/".equals(typeMapping) ? mapping[0] : typeMapping + mapping[0]; + return typeMapping == null || "/".equals(typeMapping) ? mapping[0] : join(typeMapping, mapping[0]); + } + + private String join(String typeMapping, String mapping) { + StringBuilder builder = new StringBuilder(); + + builder.append(typeMapping.endsWith("/") ? typeMapping.substring(0, typeMapping.length() - 1) : typeMapping); + builder.append('/'); + builder.append(mapping.startsWith("/") ? mapping.substring(1) : mapping); + + return builder.toString(); } private String[] getMappingFrom(Annotation annotation) { diff --git a/src/test/java/org/springframework/hateoas/core/AnnotationMappingDiscovererUnitTest.java b/src/test/java/org/springframework/hateoas/core/AnnotationMappingDiscovererUnitTest.java index c45b4968..3b5e3beb 100644 --- a/src/test/java/org/springframework/hateoas/core/AnnotationMappingDiscovererUnitTest.java +++ b/src/test/java/org/springframework/hateoas/core/AnnotationMappingDiscovererUnitTest.java @@ -21,7 +21,9 @@ import static org.junit.Assert.*; import java.lang.reflect.Method; import org.junit.Test; +import org.springframework.http.HttpEntity; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; /** * Unit tests for {@link AnnotationMappingDiscoverer}. @@ -97,6 +99,25 @@ public class AnnotationMappingDiscovererUnitTest { assertThat(discoverer.getMapping(ChildWithTypeMapping.class, method), is("/child/parent")); } + /** + * @see #269 + */ + @Test + public void handlesSlashes() throws Exception { + + Method method = ControllerWithoutSlashes.class.getMethod("noslash"); + assertThat(discoverer.getMapping(method), is("slashes/noslash")); + + method = ControllerWithoutSlashes.class.getMethod("withslash"); + assertThat(discoverer.getMapping(method), is("slashes/withslash")); + + method = ControllerWithTrailingSlashes.class.getMethod("noslash"); + assertThat(discoverer.getMapping(method), is("trailing/noslash")); + + method = ControllerWithTrailingSlashes.class.getMethod("withslash"); + assertThat(discoverer.getMapping(method), is("trailing/withslash")); + } + @RequestMapping("/type") interface MyController { @@ -139,4 +160,24 @@ public class AnnotationMappingDiscovererUnitTest { @RequestMapping("/child") interface ChildWithTypeMapping extends ParentWithMethod {} + + @RequestMapping("slashes") + interface ControllerWithoutSlashes { + + @RequestMapping("noslash") + void noslash(); + + @RequestMapping("/withslash") + void withslash(); + } + + @RequestMapping("trailing/") + interface ControllerWithTrailingSlashes { + + @RequestMapping("noslash") + void noslash(); + + @RequestMapping("/withslash") + void withslash(); + } }