From f1c3299550e63006f38c88a5b0673bef80cfc66c Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Mon, 26 Jun 2023 19:28:19 +0200 Subject: [PATCH] Adapt no-arg value from interface-based InvocationHandler callback Closes gh-30756 --- .../annotation/MvcUriComponentsBuilder.java | 4 +- .../MvcUriComponentsBuilderTests.java | 46 +++++++++++++++++-- 2 files changed, 45 insertions(+), 5 deletions(-) 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 5086cf055e7e..839b51d51d3b 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 @@ -745,8 +745,8 @@ public Object intercept(@Nullable Object obj, Method method, Object[] args, @Nul @Override @Nullable - public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { - return intercept(proxy, method, args, null); + public Object invoke(Object proxy, Method method, @Nullable Object[] args) { + return intercept(proxy, method, (args != null ? args : new Object[0]), null); } @Override 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 4e988c324009..daab23fab351 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 @@ -293,6 +293,14 @@ public void fromMethodNameWithMetaAnnotation() { assertThat(uriComponents.toUriString()).isEqualTo("http://localhost/input"); } + @Test + public void fromMethodCallOnSubclass() { + UriComponents uriComponents = fromMethodCall(on(ExtendedController.class).myMethod(null)).build(); + + assertThat(uriComponents.toUriString()).startsWith("http://localhost"); + assertThat(uriComponents.toUriString()).endsWith("/extended/else"); + } + @Test public void fromMethodCallPlain() { UriComponents uriComponents = fromMethodCall(on(ControllerWithMethods.class).myMethod(null)).build(); @@ -302,11 +310,27 @@ public void fromMethodCallPlain() { } @Test - public void fromMethodCallOnSubclass() { - UriComponents uriComponents = fromMethodCall(on(ExtendedController.class).myMethod(null)).build(); + public void fromMethodCallPlainWithNoArguments() { + UriComponents uriComponents = fromMethodCall(on(ControllerWithMethods.class).myMethod()).build(); assertThat(uriComponents.toUriString()).startsWith("http://localhost"); - assertThat(uriComponents.toUriString()).endsWith("/extended/else"); + assertThat(uriComponents.toUriString()).endsWith("/something/noarg"); + } + + @Test + public void fromMethodCallPlainOnInterface() { + UriComponents uriComponents = fromMethodCall(on(ControllerInterface.class).myMethod(null)).build(); + + assertThat(uriComponents.toUriString()).startsWith("http://localhost"); + assertThat(uriComponents.toUriString()).endsWith("/something/else"); + } + + @Test + public void fromMethodCallPlainWithNoArgumentsOnInterface() { + UriComponents uriComponents = fromMethodCall(on(ControllerInterface.class).myMethod()).build(); + + assertThat(uriComponents.toUriString()).startsWith("http://localhost"); + assertThat(uriComponents.toUriString()).endsWith("/something/noarg"); } @Test @@ -575,6 +599,11 @@ HttpEntity myMethod(@RequestBody Object payload) { return null; } + @RequestMapping("/noarg") + HttpEntity myMethod() { + return null; + } + @RequestMapping("/{id}/foo") HttpEntity methodWithPathVariable(@PathVariable String id) { return null; @@ -616,6 +645,17 @@ static class ExtendedController extends ControllerWithMethods { } + @RequestMapping("/something") + public interface ControllerInterface { + + @RequestMapping("/else") + HttpEntity myMethod(@RequestBody Object payload); + + @RequestMapping("/noarg") + HttpEntity myMethod(); + } + + @RequestMapping("/user/{userId}/contacts") static class UserContactController {