Add missing attributes to FilterRegistration annotation

See gh-45005
This commit is contained in:
Daeho Kwon 2025-04-10 12:14:05 +02:00 committed by Moritz Halbritter
parent 75bc4b2888
commit 17d579f374
3 changed files with 61 additions and 1 deletions

View File

@ -24,6 +24,7 @@ import java.lang.annotation.Target;
import jakarta.servlet.DispatcherType; import jakarta.servlet.DispatcherType;
import jakarta.servlet.Filter; import jakarta.servlet.Filter;
import jakarta.servlet.annotation.WebInitParam;
import org.springframework.core.Ordered; import org.springframework.core.Ordered;
import org.springframework.core.annotation.AliasFor; import org.springframework.core.annotation.AliasFor;
@ -34,6 +35,7 @@ import org.springframework.core.annotation.Order;
* annotation-based alternative to {@link FilterRegistrationBean}. * annotation-based alternative to {@link FilterRegistrationBean}.
* *
* @author Moritz Halbritter * @author Moritz Halbritter
* @author Daeho Kwon
* @since 3.5.0 * @since 3.5.0
* @see FilterRegistrationBean * @see FilterRegistrationBean
*/ */
@ -81,6 +83,12 @@ public @interface FilterRegistration {
*/ */
boolean ignoreRegistrationFailure() default false; boolean ignoreRegistrationFailure() default false;
/**
* Init parameters to be used with the filter.
* @return the init parameters
*/
WebInitParam[] initParameters() default {};
/** /**
* Whether the filter mappings should be matched after any declared Filter mappings of * Whether the filter mappings should be matched after any declared Filter mappings of
* the ServletContext. * the ServletContext.
@ -95,6 +103,12 @@ public @interface FilterRegistration {
*/ */
String[] servletNames() default {}; String[] servletNames() default {};
/**
* Servlet types that the filter will be registered against.
* @return the servlet types
*/
Class<?>[] servletRegistrationBeans() default {};
/** /**
* URL patterns, as defined in the Servlet specification, that the filter will be * URL patterns, as defined in the Servlet specification, that the filter will be
* registered against. * registered against.

View File

@ -35,6 +35,7 @@ import java.util.stream.Collectors;
import jakarta.servlet.Filter; import jakarta.servlet.Filter;
import jakarta.servlet.MultipartConfigElement; import jakarta.servlet.MultipartConfigElement;
import jakarta.servlet.Servlet; import jakarta.servlet.Servlet;
import jakarta.servlet.annotation.WebInitParam;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
@ -63,6 +64,7 @@ import org.springframework.util.StringUtils;
* @author Phillip Webb * @author Phillip Webb
* @author Brian Clozel * @author Brian Clozel
* @author Moritz Halbritter * @author Moritz Halbritter
* @author Daeho Kwon
* @since 1.4.0 * @since 1.4.0
*/ */
public class ServletContextInitializerBeans extends AbstractCollection<ServletContextInitializer> { public class ServletContextInitializerBeans extends AbstractCollection<ServletContextInitializer> {
@ -362,6 +364,17 @@ public class ServletContextInitializerBeans extends AbstractCollection<ServletCo
bean.setMatchAfter(registration.matchAfter()); bean.setMatchAfter(registration.matchAfter());
bean.setServletNames(Arrays.asList(registration.servletNames())); bean.setServletNames(Arrays.asList(registration.servletNames()));
bean.setUrlPatterns(Arrays.asList(registration.urlPatterns())); bean.setUrlPatterns(Arrays.asList(registration.urlPatterns()));
for (WebInitParam param : registration.initParameters()) {
bean.addInitParameter(param.name(), param.value());
}
this.beanFactory.getBeanProvider(ServletRegistrationBean.class).forEach((servletRegistrationBean) -> {
for (Class<?> servletClass : registration.servletRegistrationBeans()) {
if (servletClass.isInstance(servletRegistrationBean.getServlet())) {
bean.addServletRegistrationBeans(servletRegistrationBean);
}
}
});
} }
} }

View File

@ -16,6 +16,7 @@
package org.springframework.boot.web.servlet; package org.springframework.boot.web.servlet;
import java.util.Collection;
import java.util.EnumSet; import java.util.EnumSet;
import jakarta.servlet.DispatcherType; import jakarta.servlet.DispatcherType;
@ -25,6 +26,7 @@ import jakarta.servlet.FilterConfig;
import jakarta.servlet.ServletContext; import jakarta.servlet.ServletContext;
import jakarta.servlet.ServletRequest; import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse; import jakarta.servlet.ServletResponse;
import jakarta.servlet.annotation.WebInitParam;
import jakarta.servlet.http.HttpServlet; import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
@ -47,6 +49,7 @@ import static org.assertj.core.api.Assertions.assertThat;
* *
* @author Andy Wilkinson * @author Andy Wilkinson
* @author Moritz Halbritter * @author Moritz Halbritter
* @author Daeho Kwon
*/ */
class ServletContextInitializerBeansTests { class ServletContextInitializerBeansTests {
@ -141,6 +144,14 @@ class ServletContextInitializerBeansTests {
assertThat(filterRegistrationBean.getServletNames()).containsExactly("test"); assertThat(filterRegistrationBean.getServletNames()).containsExactly("test");
assertThat(filterRegistrationBean.determineDispatcherTypes()).containsExactly(DispatcherType.ERROR); assertThat(filterRegistrationBean.determineDispatcherTypes()).containsExactly(DispatcherType.ERROR);
assertThat(filterRegistrationBean.getUrlPatterns()).containsExactly("/test/*"); assertThat(filterRegistrationBean.getUrlPatterns()).containsExactly("/test/*");
assertThat(filterRegistrationBean.getInitParameters()).containsEntry("env", "test")
.containsEntry("debug", "true");
Collection<ServletRegistrationBean<?>> servletRegistrationBeans = filterRegistrationBean
.getServletRegistrationBeans();
assertThat(servletRegistrationBeans).hasSize(1);
assertThat(servletRegistrationBeans.iterator().next().getServletName())
.isEqualTo("testServletRegistrationBean");
}); });
} }
@ -296,11 +307,33 @@ class ServletContextInitializerBeansTests {
@Bean @Bean
@FilterRegistration(enabled = false, name = "test", asyncSupported = false, @FilterRegistration(enabled = false, name = "test", asyncSupported = false,
dispatcherTypes = DispatcherType.ERROR, matchAfter = true, servletNames = "test", dispatcherTypes = DispatcherType.ERROR, matchAfter = true, servletNames = "test",
urlPatterns = "/test/*") urlPatterns = "/test/*",
initParameters = { @WebInitParam(name = "env", value = "test"),
@WebInitParam(name = "debug", value = "true") },
servletRegistrationBeans = { TestServlet.class })
TestFilter testFilter() { TestFilter testFilter() {
return new TestFilter(); return new TestFilter();
} }
@Bean
ServletRegistrationBean<TestServlet> testServletRegistrationBean() {
return new ServletRegistrationBean<>(new TestServlet());
}
@Bean
ServletRegistrationBean<NonMatchingServlet> nonMatchingServletRegistrationBean() {
return new ServletRegistrationBean<>(new NonMatchingServlet());
}
static class NonMatchingServlet extends HttpServlet implements ServletContextInitializer {
@Override
public void onStartup(ServletContext servletContext) {
}
}
} }
@Configuration(proxyBeanMethods = false) @Configuration(proxyBeanMethods = false)