From e3f1bc8422a63ff4bac5473daaeb1062c72620d3 Mon Sep 17 00:00:00 2001 From: rstoyanchev Date: Fri, 11 Jul 2025 13:33:34 +0100 Subject: [PATCH] Allow resolution of optional HandlerMethod Closes gh-35067 --- .../web/method/support/InvocableHandlerMethod.java | 4 ++++ .../support/InvocableHandlerMethodTests.java | 14 ++++++++++++++ 2 files changed, 18 insertions(+) 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"; + } }