diff --git a/spring-web/src/main/java/org/springframework/web/method/support/InvocableHandlerMethod.java b/spring-web/src/main/java/org/springframework/web/method/support/InvocableHandlerMethod.java index 29b9606d635..c87cc74729a 100644 --- a/spring-web/src/main/java/org/springframework/web/method/support/InvocableHandlerMethod.java +++ b/spring-web/src/main/java/org/springframework/web/method/support/InvocableHandlerMethod.java @@ -217,6 +217,10 @@ public class InvocableHandlerMethod extends HandlerMethod { if (args[i] != null) { continue; } + if (parameter.getParameterType().equals(HandlerMethod.class) && parameter.isOptional()) { + args[i] = null; + continue; + } if (!this.resolvers.supportsParameter(parameter)) { throw new IllegalStateException(formatArgumentError(parameter, "No suitable resolver")); } diff --git a/spring-web/src/test/java/org/springframework/web/method/support/InvocableHandlerMethodTests.java b/spring-web/src/test/java/org/springframework/web/method/support/InvocableHandlerMethodTests.java index a919a964253..a2d06b9bb1d 100644 --- a/spring-web/src/test/java/org/springframework/web/method/support/InvocableHandlerMethodTests.java +++ b/spring-web/src/test/java/org/springframework/web/method/support/InvocableHandlerMethodTests.java @@ -18,6 +18,7 @@ package org.springframework.web.method.support; import java.lang.reflect.Method; +import org.jspecify.annotations.Nullable; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -25,6 +26,7 @@ import org.springframework.core.MethodParameter; import org.springframework.web.bind.support.WebDataBinderFactory; import org.springframework.web.context.request.NativeWebRequest; import org.springframework.web.context.request.ServletWebRequest; +import org.springframework.web.method.HandlerMethod; import org.springframework.web.testfixture.method.ResolvableMethod; import org.springframework.web.testfixture.servlet.MockHttpServletRequest; import org.springframework.web.testfixture.servlet.MockHttpServletResponse; @@ -105,6 +107,14 @@ class InvocableHandlerMethodTests { assertThat(value).isEqualTo("2-value2"); } + @Test + void resolveHandlerMethodArgToNull() throws Exception { + Object value = getInvocable(HandlerMethod.class).invokeForRequest(request, null); + + assertThat(value).isNotNull(); + assertThat(value).isEqualTo("success"); + } + @Test void exceptionInResolvingArg() { this.composite.addResolver(new ExceptionRaisingArgumentResolver()); @@ -184,6 +194,10 @@ class InvocableHandlerMethodTests { public void handleWithException(Throwable ex) throws Throwable { throw ex; } + + public String handleHandlerMethod(@Nullable HandlerMethod handlerMethod) { + return "success"; + } }