GH-3366: Return null from HTTP handleNoMatch
Fixes: https://github.com/spring-projects/spring-integration/issues/3366 When the same path is mapped for integration HTTP endpoint and MVC method mapping, but different other mapping options (e.g. method) and one of them fails to match, there is no way to try other `RequestMapping` from the `DispatcherServlet` because `RequestMappingHandlerMapping.handleNoMatch()` throws an exception when no match instead of `null` according chain of responsibility logic in the `DispatcherServlet` * Rework `IntegrationRequestMappingHandlerMapping.handleNoMatch()` to catch all the super exception and return `null` to the `DispatcherServlet` to let it to try other `RequestMapping` from the configuration * Change an order for `IntegrationRequestMappingHandlerMapping` to `-1` to let it to be tried first before regular MVC `RequestMappingHandlerMapping` * Add a test-case to ensure that mix-in Integration HTTP and MVC for the same path works as expected without failing on first try
This commit is contained in:
committed by
Gary Russell
parent
09dec2eab5
commit
9aa9707f37
@@ -55,8 +55,7 @@ public class HttpIntegrationConfigurationInitializer implements IntegrationConfi
|
||||
* which could also be overridden by the user by simply registering
|
||||
* a {@link IntegrationRequestMappingHandlerMapping} {@code <bean>} with 'id'
|
||||
* {@link HttpContextUtils#HANDLER_MAPPING_BEAN_NAME}.
|
||||
* <p>
|
||||
* In addition, checks if the {@code javax.servlet.Servlet} class is present on the classpath.
|
||||
* <p> In addition, checks if the {@code javax.servlet.Servlet} class is present on the classpath.
|
||||
* When Spring Integration HTTP is used only as an HTTP client, there is no reason to use and register
|
||||
* the HTTP server components.
|
||||
*/
|
||||
@@ -64,9 +63,9 @@ public class HttpIntegrationConfigurationInitializer implements IntegrationConfi
|
||||
if (HttpContextUtils.WEB_MVC_PRESENT &&
|
||||
!registry.containsBeanDefinition(HttpContextUtils.HANDLER_MAPPING_BEAN_NAME)) {
|
||||
BeanDefinitionBuilder requestMappingBuilder =
|
||||
BeanDefinitionBuilder.genericBeanDefinition(IntegrationRequestMappingHandlerMapping.class);
|
||||
requestMappingBuilder.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
|
||||
requestMappingBuilder.addPropertyValue(IntegrationNamespaceUtils.ORDER, 0);
|
||||
BeanDefinitionBuilder.genericBeanDefinition(IntegrationRequestMappingHandlerMapping.class)
|
||||
.setRole(BeanDefinition.ROLE_INFRASTRUCTURE)
|
||||
.addPropertyValue(IntegrationNamespaceUtils.ORDER, -1);
|
||||
registry.registerBeanDefinition(HttpContextUtils.HANDLER_MAPPING_BEAN_NAME,
|
||||
requestMappingBuilder.getBeanDefinition());
|
||||
}
|
||||
|
||||
@@ -21,8 +21,10 @@ import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
@@ -177,6 +179,18 @@ public final class IntegrationRequestMappingHandlerMapping extends RequestMappin
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected HandlerMethod handleNoMatch(Set<RequestMappingInfo> infos, String path, HttpServletRequest request) {
|
||||
try {
|
||||
return super.handleNoMatch(infos, path, request);
|
||||
}
|
||||
catch (ServletException ex) {
|
||||
// Since this component has a higher precedence the 'null' return allows a
|
||||
// 'DispatcherServlet' to try other 'HandlerMapping'
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static CorsConfiguration buildCorsConfiguration(CrossOrigin crossOrigin, RequestMappingInfo mappingInfo) {
|
||||
CorsConfiguration config = new CorsConfiguration();
|
||||
for (RequestMethod requestMethod : crossOrigin.getMethod()) {
|
||||
|
||||
Reference in New Issue
Block a user