Add missing attributes to ServletRegistration annotation

See gh-45007

Signed-off-by: Dmytro Danilenkov <milgoff@gmail.com>
This commit is contained in:
Dmytro Danilenkov 2025-04-10 14:39:54 +02:00 committed by Moritz Halbritter
parent 475a046048
commit d0128071ec
3 changed files with 60 additions and 0 deletions

View File

@ -65,6 +65,7 @@ import org.springframework.util.StringUtils;
* @author Brian Clozel * @author Brian Clozel
* @author Moritz Halbritter * @author Moritz Halbritter
* @author Daeho Kwon * @author Daeho Kwon
* @author Dmytro Danilenkov
* @since 1.4.0 * @since 1.4.0
*/ */
public class ServletContextInitializerBeans extends AbstractCollection<ServletContextInitializer> { public class ServletContextInitializerBeans extends AbstractCollection<ServletContextInitializer> {
@ -320,6 +321,10 @@ public class ServletContextInitializerBeans extends AbstractCollection<ServletCo
bean.setIgnoreRegistrationFailure(registration.ignoreRegistrationFailure()); bean.setIgnoreRegistrationFailure(registration.ignoreRegistrationFailure());
bean.setLoadOnStartup(registration.loadOnStartup()); bean.setLoadOnStartup(registration.loadOnStartup());
bean.setUrlMappings(Arrays.asList(registration.urlMappings())); bean.setUrlMappings(Arrays.asList(registration.urlMappings()));
for (WebInitParam param : registration.initParameters()) {
bean.addInitParameter(param.name(), param.value());
}
bean.setMultipartConfig(new MultipartConfigElement(registration.multipartConfig()));
} }
} }

View File

@ -23,6 +23,8 @@ import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; import java.lang.annotation.Target;
import jakarta.servlet.Servlet; import jakarta.servlet.Servlet;
import jakarta.servlet.annotation.MultipartConfig;
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;
@ -33,6 +35,7 @@ import org.springframework.core.annotation.Order;
* annotation-based alternative to {@link ServletRegistrationBean}. * annotation-based alternative to {@link ServletRegistrationBean}.
* *
* @author Moritz Halbritter * @author Moritz Halbritter
* @author Dmytro Danilenkov
* @since 3.5.0 * @since 3.5.0
* @see ServletRegistrationBean * @see ServletRegistrationBean
*/ */
@ -87,4 +90,16 @@ public @interface ServletRegistration {
*/ */
int loadOnStartup() default -1; int loadOnStartup() default -1;
/**
* Init parameters to set on the servlet (mirrors {@code @WebInitParam} usage).
* @return array of {@link WebInitParam}
*/
WebInitParam[] initParameters() default {};
/**
* Multipart configuration.
* @return multipart config {@link MultipartConfig}
*/
MultipartConfig multipartConfig() default @MultipartConfig;
} }

View File

@ -27,6 +27,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.MultipartConfig;
import jakarta.servlet.annotation.WebInitParam; 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;
@ -51,6 +52,7 @@ import static org.assertj.core.api.Assertions.assertThat;
* @author Andy Wilkinson * @author Andy Wilkinson
* @author Moritz Halbritter * @author Moritz Halbritter
* @author Daeho Kwon * @author Daeho Kwon
* @author Dmytro Danilenkov
*/ */
class ServletContextInitializerBeansTests { class ServletContextInitializerBeansTests {
@ -207,6 +209,29 @@ class ServletContextInitializerBeansTests {
.isEqualTo(ServletConfigurationWithAnnotationAndOrder.ORDER)); .isEqualTo(ServletConfigurationWithAnnotationAndOrder.ORDER));
} }
@Test
void shouldApplyExtendedServletRegistrationAnnotation() {
load(ServletConfigurationWithExtendedAttributes.class);
ServletContextInitializerBeans initializerBeans = new ServletContextInitializerBeans(
this.context.getBeanFactory(), TestServletContextInitializer.class);
assertThatSingleServletRegistration(initializerBeans, (bean) -> {
assertThat(bean.getServletName()).isEqualTo("extended");
assertThat(bean.getUrlMappings()).containsExactly("/extended/*");
assertThat(bean.getInitParameters()).containsEntry("hello", "world").containsEntry("flag", "true");
assertThat(bean.getMultipartConfig()).isNotNull();
assertThat(bean.getMultipartConfig().getLocation()).isEqualTo("/tmp");
assertThat(bean.getMultipartConfig().getMaxFileSize()).isEqualTo(1024);
assertThat(bean.getMultipartConfig().getMaxRequestSize()).isEqualTo(4096);
assertThat(bean.getMultipartConfig().getFileSizeThreshold()).isEqualTo(128);
});
}
private void assertThatSingleServletRegistration(ServletContextInitializerBeans initializerBeans,
ThrowingConsumer<ServletRegistrationBean<?>> code) {
assertThatSingleRegistration(initializerBeans, ServletRegistrationBean.class, code::acceptThrows);
}
private void load(Class<?>... configuration) { private void load(Class<?>... configuration) {
this.context = new AnnotationConfigApplicationContext(configuration); this.context = new AnnotationConfigApplicationContext(configuration);
} }
@ -454,4 +479,19 @@ class ServletContextInitializerBeansTests {
} }
@Configuration(proxyBeanMethods = false)
static class ServletConfigurationWithExtendedAttributes {
@Bean
@ServletRegistration(name = "extended", urlMappings = "/extended/*",
initParameters = { @WebInitParam(name = "hello", value = "world"),
@WebInitParam(name = "flag", value = "true") },
multipartConfig = @MultipartConfig(location = "/tmp", maxFileSize = 1024, maxRequestSize = 4096,
fileSizeThreshold = 128))
TestServlet testServletWithInitParametersAndMultipart() {
return new TestServlet();
}
}
} }