diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/MvcUriComponentsBuilder.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/MvcUriComponentsBuilder.java index 27ef77bf84d..765823866b8 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/MvcUriComponentsBuilder.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/MvcUriComponentsBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2020 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -545,6 +545,9 @@ public class MvcUriComponentsBuilder { String typePath = getClassMapping(controllerType); String methodPath = getMethodMapping(method); String path = pathMatcher.combine(typePath, methodPath); + if (StringUtils.hasLength(path) && !path.startsWith("/")) { + path = "/" + path; + } builder.path(path); return applyContributors(builder, method, args); diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/MvcUriComponentsBuilderTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/MvcUriComponentsBuilderTests.java index 103118d8ebc..99abb24debd 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/MvcUriComponentsBuilderTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/MvcUriComponentsBuilderTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2020 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -434,6 +434,20 @@ public class MvcUriComponentsBuilderTests { assertThat(url).isEqualTo("/base/people/_%2B_/addresses/DE%3BFR"); } + @Test + public void fromMappingNameWithPathWithoutLeadingSlash() { + + initWebApplicationContext(PathWithoutLeadingSlashConfig.class); + + this.request.setServerName("example.org"); + this.request.setServerPort(9999); + this.request.setContextPath("/base"); + + String mappingName = "PWLSC#getAddressesForCountry"; + String url = fromMappingName(mappingName).arg(0, "DE;FR").encode().buildAndExpand("_+_"); + assertThat(url).isEqualTo("/base/people/DE%3BFR"); + } + @Test public void fromControllerWithPrefix() { @@ -498,6 +512,14 @@ public class MvcUriComponentsBuilderTests { } } + @RequestMapping({"people"}) + static class PathWithoutLeadingSlashController { + + @RequestMapping("/{country}") + HttpEntity getAddressesForCountry(@PathVariable String country) { + return null; + } + } @RequestMapping({"/persons", "/people"}) private class InvalidController { @@ -622,6 +644,16 @@ public class MvcUriComponentsBuilderTests { } + @EnableWebMvc + static class PathWithoutLeadingSlashConfig implements WebMvcConfigurer { + + @Bean + public PathWithoutLeadingSlashController controller() { + return new PathWithoutLeadingSlashController(); + } + } + + @EnableWebMvc static class PathPrefixWebConfig implements WebMvcConfigurer {