diff --git a/src/main/java/org/springframework/hateoas/server/core/AnnotationMappingDiscoverer.java b/src/main/java/org/springframework/hateoas/server/core/AnnotationMappingDiscoverer.java index cd794b4b..7401e4d5 100644 --- a/src/main/java/org/springframework/hateoas/server/core/AnnotationMappingDiscoverer.java +++ b/src/main/java/org/springframework/hateoas/server/core/AnnotationMappingDiscoverer.java @@ -207,7 +207,7 @@ public class AnnotationMappingDiscoverer implements MappingDiscoverer { * @return */ private static String join(String typeMapping, String mapping) { - return typeMapping.concat("/").concat(mapping); + return mapping.isBlank() ? typeMapping : typeMapping.concat("/").concat(mapping); } /** diff --git a/src/test/java/org/springframework/hateoas/server/mvc/WebMvcLinkBuilderUnitTest.java b/src/test/java/org/springframework/hateoas/server/mvc/WebMvcLinkBuilderUnitTest.java index e074bd9d..d79cccf7 100644 --- a/src/test/java/org/springframework/hateoas/server/mvc/WebMvcLinkBuilderUnitTest.java +++ b/src/test/java/org/springframework/hateoas/server/mvc/WebMvcLinkBuilderUnitTest.java @@ -748,7 +748,18 @@ class WebMvcLinkBuilderUnitTest extends TestUtils { linkTo(methodOn(ControllerWithPathVariableCatchAll.class).test("first", it[0])).withSelfRel().getHref()) .endsWith(it[1]); }); + } + @Test // #1886 + void doesNotAppendTrailingSlashForEmptyMapping() { + + var controller = methodOn(PersonController.class); + + assertThat(linkTo(controller.getMappingWithoutPath()).toString()) + .isEqualTo("http://localhost/people"); + + assertThat(linkTo(controller.getMappingWithEmptyPath()).toString()) + .isEqualTo("http://localhost/people"); } private static UriComponents toComponents(Link link) { @@ -760,7 +771,18 @@ class WebMvcLinkBuilderUnitTest extends TestUtils { } @RequestMapping("/people") - interface PersonController {} + interface PersonController { + + @GetMapping + default Object getMappingWithoutPath() { + return null; + } + + @GetMapping("") + default Object getMappingWithEmptyPath() { + return null; + } + } class PersonControllerImpl implements PersonController {}