Refine empty path handling in MvcUriComponentsBuilder
Return "" from methods that obtain controller or method mapping to avoid side effect of a trailing slash appearing. Closes gh-29897
This commit is contained in:
@@ -180,6 +180,7 @@ public class MvcUriComponentsBuilder {
|
||||
builder.path(prefix);
|
||||
|
||||
String mapping = getClassMapping(controllerType);
|
||||
mapping = (!StringUtils.hasText(prefix + mapping) ? "/" : mapping);
|
||||
builder.path(mapping);
|
||||
|
||||
return builder;
|
||||
@@ -280,10 +281,10 @@ public class MvcUriComponentsBuilder {
|
||||
* @RequestMapping("/people/{id}/addresses")
|
||||
* class AddressController {
|
||||
*
|
||||
* @RequestMapping("/{country}")
|
||||
* @GetMapping("/{country}")
|
||||
* public HttpEntity<Void> getAddressesForCountry(@PathVariable String country) { ... }
|
||||
*
|
||||
* @RequestMapping(value="/", method=RequestMethod.POST)
|
||||
* @PostMapping
|
||||
* public void addAddress(Address address) { ... }
|
||||
* }
|
||||
* </pre>
|
||||
@@ -546,6 +547,9 @@ public class MvcUriComponentsBuilder {
|
||||
if (StringUtils.hasLength(path) && !path.startsWith("/")) {
|
||||
path = "/" + path;
|
||||
}
|
||||
else if (!StringUtils.hasText(prefix + path)) {
|
||||
path = "/";
|
||||
}
|
||||
builder.path(path);
|
||||
|
||||
return applyContributors(builder, method, args);
|
||||
@@ -577,11 +581,11 @@ public class MvcUriComponentsBuilder {
|
||||
Assert.notNull(controllerType, "'controllerType' must not be null");
|
||||
RequestMapping mapping = AnnotatedElementUtils.findMergedAnnotation(controllerType, RequestMapping.class);
|
||||
if (mapping == null) {
|
||||
return "/";
|
||||
return "";
|
||||
}
|
||||
String[] paths = mapping.path();
|
||||
if (ObjectUtils.isEmpty(paths) || !StringUtils.hasLength(paths[0])) {
|
||||
return "/";
|
||||
return "";
|
||||
}
|
||||
if (paths.length > 1 && logger.isTraceEnabled()) {
|
||||
logger.trace("Using first of multiple paths on " + controllerType.getName());
|
||||
@@ -597,7 +601,7 @@ public class MvcUriComponentsBuilder {
|
||||
}
|
||||
String[] paths = requestMapping.path();
|
||||
if (ObjectUtils.isEmpty(paths) || !StringUtils.hasLength(paths[0])) {
|
||||
return "/";
|
||||
return "";
|
||||
}
|
||||
if (paths.length > 1 && logger.isTraceEnabled()) {
|
||||
logger.trace("Using first of multiple paths on " + method.toGenericString());
|
||||
@@ -845,7 +849,7 @@ public class MvcUriComponentsBuilder {
|
||||
public MethodArgumentBuilder(@Nullable UriComponentsBuilder baseUrl, Class<?> controllerType, Method method) {
|
||||
Assert.notNull(controllerType, "'controllerType' is required");
|
||||
Assert.notNull(method, "'method' is required");
|
||||
this.baseUrl = baseUrl != null ? baseUrl : UriComponentsBuilder.fromPath(getPath());
|
||||
this.baseUrl = (baseUrl != null ? baseUrl : UriComponentsBuilder.fromPath(getPath()));
|
||||
this.controllerType = controllerType;
|
||||
this.method = method;
|
||||
this.argumentValues = new Object[method.getParameterCount()];
|
||||
@@ -854,7 +858,7 @@ public class MvcUriComponentsBuilder {
|
||||
private static String getPath() {
|
||||
UriComponentsBuilder builder = ServletUriComponentsBuilder.fromCurrentServletMapping();
|
||||
String path = builder.build().getPath();
|
||||
return path != null ? path : "";
|
||||
return (path != null ? path : "");
|
||||
}
|
||||
|
||||
public MethodArgumentBuilder arg(int index, Object value) {
|
||||
|
||||
@@ -234,12 +234,19 @@ public class MvcUriComponentsBuilderTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void fromMethodNameNotMapped() {
|
||||
UriComponents uriComponents = fromMethodName(UnmappedController.class, "unmappedMethod").build();
|
||||
public void fromMethodNameInUnmappedController() {
|
||||
UriComponents uriComponents = fromMethodName(UnmappedController.class, "requestMappingMethod").build();
|
||||
|
||||
assertThat(uriComponents.toUriString()).isEqualTo("http://localhost/");
|
||||
}
|
||||
|
||||
@Test // gh-29897
|
||||
public void fromMethodNameInUnmappedControllerMethod() {
|
||||
UriComponents uriComponents = fromMethodName(UnmappedControllerMethod.class, "getMethod").build();
|
||||
|
||||
assertThat(uriComponents.toUriString()).isEqualTo("http://localhost/path");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void fromMethodNameWithCustomBaseUrlViaStaticCall() {
|
||||
UriComponentsBuilder builder = UriComponentsBuilder.fromUriString("https://example.org:9090/base");
|
||||
@@ -535,7 +542,16 @@ public class MvcUriComponentsBuilderTests {
|
||||
private class UnmappedController {
|
||||
|
||||
@RequestMapping
|
||||
public void unmappedMethod() {
|
||||
public void requestMappingMethod() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@RequestMapping("/path")
|
||||
private class UnmappedControllerMethod {
|
||||
|
||||
@GetMapping
|
||||
public void getMethod() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user