From cdbaee11c13f07457d27785088e1d13e931a9f1d Mon Sep 17 00:00:00 2001 From: rstoyanchev Date: Fri, 13 Mar 2026 14:51:39 +0000 Subject: [PATCH 1/2] Add PreFlightRequestFilter Closes gh-36482 --- .../web/filter/PreFlightRequestFilter.java | 71 +++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 spring-web/src/main/java/org/springframework/web/filter/PreFlightRequestFilter.java diff --git a/spring-web/src/main/java/org/springframework/web/filter/PreFlightRequestFilter.java b/spring-web/src/main/java/org/springframework/web/filter/PreFlightRequestFilter.java new file mode 100644 index 00000000000..6cd3af74148 --- /dev/null +++ b/spring-web/src/main/java/org/springframework/web/filter/PreFlightRequestFilter.java @@ -0,0 +1,71 @@ +/* + * Copyright 2002-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.web.filter; + +import java.io.IOException; + +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; + +import org.springframework.util.Assert; +import org.springframework.web.cors.CorsUtils; +import org.springframework.web.cors.PreFlightRequestHandler; + +/** + * Servlet Filter that handles pre-flight requests through a + * {@link PreFlightRequestHandler} and bypasses the rest of the chain. + * + *

The {@code @EnableWebMvc} config declares bean of type + * {@code PreFlightRequestHandler}. + * + * @author Rossen Stoyanchev + * @since 7.0.7 + */ +public class PreFlightRequestFilter extends OncePerRequestFilter { + + private final PreFlightRequestHandler handler; + + + public PreFlightRequestFilter(PreFlightRequestHandler handler) { + Assert.notNull(handler, "PreFlightRequestHandler is required"); + this.handler = handler; + } + + + @Override + protected void doFilterInternal( + HttpServletRequest request, HttpServletResponse response, FilterChain chain) + throws ServletException, IOException { + + if (!CorsUtils.isPreFlightRequest(request)) { + chain.doFilter(request, response); + return; + } + + try { + this.handler.handlePreFlight(request, response); + } + catch (ServletException | IOException ex) { + throw ex; + } + catch (Throwable ex) { + throw new ServletException("Pre-flight request handling failed: " + ex, ex); + } + } +} From 8817536e5a9243883529ba94f26e3b5a209f0a07 Mon Sep 17 00:00:00 2001 From: rstoyanchev Date: Tue, 17 Mar 2026 19:00:34 +0000 Subject: [PATCH 2/2] Lower log level of cache miss in HandlerMappingIntrospector See gh-36309 --- .../web/servlet/handler/HandlerMappingIntrospector.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/HandlerMappingIntrospector.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/HandlerMappingIntrospector.java index 47d28d847e1..0fbdb2fe285 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/HandlerMappingIntrospector.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/HandlerMappingIntrospector.java @@ -518,8 +518,8 @@ public class HandlerMappingIntrospector String message = getLogMessage(label, request); - if (logger.isWarnEnabled() && counter.getAndIncrement() == 0) { - logger.warn(message + " This is logged once only at WARN level, and every time at TRACE."); + if (logger.isDebugEnabled() && counter.getAndIncrement() == 0) { + logger.debug(message + " This is logged once only at DEBUG level, and every time at TRACE."); } else if (logger.isTraceEnabled()) { logger.trace("No CachedResult, performing " + label + " lookup instead."); @@ -529,7 +529,9 @@ public class HandlerMappingIntrospector private static String getLogMessage(String label, HttpServletRequest request) { return "Cache miss for " + request.getDispatcherType() + " dispatch to '" + request.getRequestURI() + "' " + "(previous " + request.getAttribute(CACHED_RESULT_ATTRIBUTE) + "). " + - "Performing " + label + " lookup."; + "Performing " + label + " lookup. If there are repeated lookups per request, " + + "consider using HandlerMappingIntrospector#createCacheFilter()" + + "to create a Servlet Filter to set the cache for the request."; } }