Skip to content

Commit da9173b

Browse files
Fix for issue #45001 - ServletRegistrationBean has those properties, but @ServletRegistration hasn't: initParameters, servletRegistrationBeans, multipartConfig Signed-off-by: Dmytro Danilenkov <[email protected]>
Signed-off-by: Dmytro Danilenkov <[email protected]>
1 parent 12bf433 commit da9173b

File tree

3 files changed

+36
-154
lines changed

3 files changed

+36
-154
lines changed

spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/ServletContextInitializerBeans.java

Lines changed: 13 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@
3535
import jakarta.servlet.Filter;
3636
import jakarta.servlet.MultipartConfigElement;
3737
import jakarta.servlet.Servlet;
38+
import jakarta.servlet.annotation.MultipartConfig;
39+
import jakarta.servlet.annotation.WebInitParam;
40+
3841
import org.apache.commons.logging.Log;
3942
import org.apache.commons.logging.LogFactory;
4043

@@ -324,57 +327,24 @@ private void configureFromAnnotation(ServletRegistrationBean<Servlet> bean, Serv
324327
}
325328

326329
if (registration.initParameters().length > 0) {
327-
bean.setInitParameters(parseInitParameters(registration.initParameters()));
330+
Map<String, String> initParams = new LinkedHashMap<>();
331+
for (WebInitParam param : registration.initParameters()) {
332+
initParams.put(param.name(), param.value());
333+
}
334+
bean.setInitParameters(initParams);
328335
}
329336

330-
ServletRegistration.MultipartConfigValues multipart = registration.multipartConfig();
331-
boolean isMultipartConfigUsed = !(multipart.location().isEmpty()
332-
&& multipart.maxFileSize() == -1L
333-
&& multipart.maxRequestSize() == -1L
334-
&& multipart.fileSizeThreshold() == 0);
337+
MultipartConfig multipart = registration.multipartConfig();
338+
boolean isMultipartConfigUsed = !(multipart.location().isEmpty() && multipart.maxFileSize() == -1L
339+
&& multipart.maxRequestSize() == -1L && multipart.fileSizeThreshold() == 0);
335340
if (isMultipartConfigUsed) {
336-
bean.setMultipartConfig(new MultipartConfigElement(
337-
multipart.location(),
338-
multipart.maxFileSize(),
339-
multipart.maxRequestSize(),
340-
multipart.fileSizeThreshold()
341-
));
342-
}
343-
344-
for (Class<? extends ServletRegistrationBean<?>> beanClass : registration.servletRegistrationBeans()) {
345-
ServletRegistrationBean<?> extraBean = this.beanFactory.getBean(beanClass);
346-
bean.getInitParameters().putAll(extraBean.getInitParameters());
347-
}
348-
349-
}
350-
351-
/**
352-
* Parses an array of "key=value" strings into a Map.
353-
* @param initParamsArray Array of strings, expected format "key=value".
354-
* @return Map of parsed key-value pairs.
355-
* @throws IllegalArgumentException if any string doesn't match the "key=value" format.
356-
*/
357-
private Map<String, String> parseInitParameters(String[] initParamsArray) {
358-
Map<String, String> initParams = new LinkedHashMap<>();
359-
for (String kv : initParamsArray) {
360-
int index = kv.indexOf('=');
361-
if (index != -1) {
362-
String key = kv.substring(0, index).trim();
363-
String value = kv.substring(index + 1).trim();
364-
initParams.put(key, value);
365-
}
366-
else {
367-
throw new IllegalArgumentException(
368-
"initParameters must be in 'key=value' format, got: " + kv);
369-
}
341+
bean.setMultipartConfig(new MultipartConfigElement(multipart.location(), multipart.maxFileSize(),
342+
multipart.maxRequestSize(), multipart.fileSizeThreshold()));
370343
}
371-
return initParams;
372344
}
373345

374346
}
375347

376-
377-
378348
/**
379349
* {@link RegistrationBeanAdapter} for {@link Filter} beans.
380350
*/

spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/servlet/ServletRegistration.java

Lines changed: 5 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -91,49 +91,14 @@
9191
int loadOnStartup() default -1;
9292

9393
/**
94-
* Init parameters to set on the servlet, as {@code "key=value"} pairs.
94+
* Init parameters to set on the servlet (mirrors {@code @WebInitParam} usage).
95+
* @return array of {@link WebInitParam}
9596
*/
96-
String[] initParameters() default {};
97+
WebInitParam[] initParameters() default {};
9798

9899
/**
99-
* (Optional) Additional servlet-registration beans to apply.
100-
* Usually left empty unless you need custom bean logic.
100+
* Multipart configuration.
101101
*/
102-
Class<? extends ServletRegistrationBean<?>>[] servletRegistrationBeans() default {};
102+
MultipartConfig multipartConfig() default @MultipartConfig;
103103

104-
/**
105-
* Multipart configuration. Mirrors {@link jakarta.servlet.annotation.MultipartConfig}.
106-
* If you omit it (no fields changed), it will not set a multipart config.
107-
*/
108-
MultipartConfigValues multipartConfig() default @MultipartConfigValues;
109-
110-
/**
111-
* Nested annotation that parallels the fields of
112-
* {@link jakarta.servlet.annotation.MultipartConfig}. Used within
113-
* {@link ServletRegistration#multipartConfig()}.
114-
* @see jakarta.servlet.annotation.MultipartConfig
115-
*/
116-
@Target({})
117-
@Retention(RetentionPolicy.RUNTIME)
118-
@Documented
119-
@interface MultipartConfigValues {
120-
121-
/**
122-
* @see jakarta.servlet.annotation.MultipartConfig#location()
123-
*/
124-
String location() default "";
125-
/**
126-
* @see jakarta.servlet.annotation.MultipartConfig#maxFileSize()
127-
*/
128-
long maxFileSize() default -1L;
129-
/**
130-
* @see jakarta.servlet.annotation.MultipartConfig#maxRequestSize()
131-
*/
132-
long maxRequestSize() default -1L;
133-
/**
134-
* @see jakarta.servlet.annotation.MultipartConfig#fileSizeThreshold()
135-
*/
136-
int fileSizeThreshold() default 0;
137-
138-
}
139104
}

spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/servlet/ServletContextInitializerBeansTests.java

Lines changed: 18 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
import jakarta.servlet.ServletContext;
2424
import jakarta.servlet.ServletRequest;
2525
import jakarta.servlet.ServletResponse;
26+
import jakarta.servlet.annotation.MultipartConfig;
27+
import jakarta.servlet.annotation.WebInitParam;
2628
import jakarta.servlet.http.HttpServlet;
2729
import jakarta.servlet.http.HttpSessionIdListener;
2830
import org.assertj.core.api.ThrowingConsumer;
@@ -191,8 +193,7 @@ void shouldApplyExtendedServletRegistrationAnnotation() {
191193
assertThat(bean.getServletName()).isEqualTo("extended");
192194
assertThat(bean.getUrlMappings()).containsExactly("/extended/*");
193195

194-
assertThat(bean.getInitParameters()).containsEntry("hello", "world")
195-
.containsEntry("flag", "true");
196+
assertThat(bean.getInitParameters()).containsEntry("hello", "world").containsEntry("flag", "true");
196197

197198
assertThat(bean.getMultipartConfig()).isNotNull();
198199
assertThat(bean.getMultipartConfig().getLocation()).isEqualTo("/tmp");
@@ -201,33 +202,7 @@ void shouldApplyExtendedServletRegistrationAnnotation() {
201202
assertThat(bean.getMultipartConfig().getFileSizeThreshold()).isEqualTo(128);
202203
}
203204

204-
@Test
205-
void shouldApplyServletRegistrationAnnotationWithExtraRegistrationBeans() {
206-
load(ServletConfigurationWithExtendedAttributes.class);
207-
ServletContextInitializerBeans initializerBeans = new ServletContextInitializerBeans(
208-
this.context.getBeanFactory(), TestServletContextInitializer.class);
209-
210-
ServletRegistrationBean<?> bean = findServletRegistrationBeanByName(initializerBeans, "extendedWithExtraBeans");
211-
assertThat(bean).as("extendedWithExtraBeans registration bean").isNotNull();
212-
213-
assertThat(bean.getServletName()).isEqualTo("extendedWithExtraBeans");
214-
assertThat(bean.getUrlMappings()).containsExactly("/extra/*");
215-
216-
assertThat(bean.getInitParameters()).containsEntry("extra", "fromExtraBean");
217-
}
218-
219-
@SuppressWarnings("rawtypes")
220-
private ServletRegistrationBean findServletRegistrationBeanByName(
221-
ServletContextInitializerBeans initializerBeans, String servletName) {
222-
223-
return initializerBeans.stream()
224-
.filter(ServletRegistrationBean.class::isInstance)
225-
.map(ServletRegistrationBean.class::cast)
226-
.filter((registrationBean) -> servletName.equals(registrationBean.getServletName()))
227-
.findFirst()
228-
.orElse(null);
229-
}
230-
205+
// Removed the test that relied on servletRegistrationBeans = { ... }
231206

232207
private void load(Class<?>... configuration) {
233208
this.context = new AnnotationConfigApplicationContext(configuration);
@@ -377,7 +352,6 @@ static class TestServlet extends HttpServlet implements ServletContextInitialize
377352

378353
@Override
379354
public void onStartup(ServletContext servletContext) {
380-
381355
}
382356

383357
}
@@ -388,7 +362,6 @@ static class OrderedTestServlet extends HttpServlet implements ServletContextIni
388362

389363
@Override
390364
public void onStartup(ServletContext servletContext) {
391-
392365
}
393366

394367
@Override
@@ -402,17 +375,14 @@ static class TestFilter implements Filter, ServletContextInitializer {
402375

403376
@Override
404377
public void onStartup(ServletContext servletContext) {
405-
406378
}
407379

408380
@Override
409381
public void init(FilterConfig filterConfig) {
410-
411382
}
412383

413384
@Override
414385
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
415-
416386
}
417387

418388
}
@@ -421,7 +391,6 @@ static class TestServletContextInitializer implements ServletContextInitializer
421391

422392
@Override
423393
public void onStartup(ServletContext servletContext) {
424-
425394
}
426395

427396
}
@@ -430,7 +399,6 @@ static class OtherTestServletContextInitializer implements ServletContextInitial
430399

431400
@Override
432401
public void onStartup(ServletContext servletContext) {
433-
434402
}
435403

436404
}
@@ -439,46 +407,25 @@ public void onStartup(ServletContext servletContext) {
439407
static class ServletConfigurationWithExtendedAttributes {
440408

441409
@Bean
442-
@ServletRegistration(
443-
name = "extended",
444-
urlMappings = "/extended/*",
445-
initParameters = { "hello=world", "flag=true" },
446-
multipartConfig = @ServletRegistration.MultipartConfigValues(
447-
location = "/tmp",
448-
maxFileSize = 1024,
449-
maxRequestSize = 4096,
450-
fileSizeThreshold = 128
451-
)
452-
)
410+
@ServletRegistration(name = "extended", urlMappings = "/extended/*",
411+
initParameters = { @WebInitParam(name = "hello", value = "world"),
412+
@WebInitParam(name = "flag", value = "true") },
413+
multipartConfig = @MultipartConfig(location = "/tmp", maxFileSize = 1024, maxRequestSize = 4096,
414+
fileSizeThreshold = 128))
453415
TestServlet testServletWithInitParametersAndMultipart() {
454416
return new TestServlet();
455417
}
456418

457-
@Bean
458-
MyExtraServletRegistrationBean myExtraServletRegistrationBean() {
459-
MyExtraServletRegistrationBean bean = new MyExtraServletRegistrationBean();
460-
bean.addInitParameter("extra", "fromExtraBean");
461-
return bean;
462-
}
463-
464-
@Bean
465-
@ServletRegistration(
466-
name = "extendedWithExtraBeans",
467-
urlMappings = "/extra/*",
468-
servletRegistrationBeans = { MyExtraServletRegistrationBean.class }
469-
)
470-
TestServlet testServletWithExtraBean() {
471-
return new TestServlet();
472-
}
473-
474-
static class MyExtraServletRegistrationBean extends ServletRegistrationBean<HttpServlet> {
475-
476-
MyExtraServletRegistrationBean() {
477-
super();
478-
}
479-
480-
}
481419
}
482420

421+
private ServletRegistrationBean<?> findServletRegistrationBeanByName(
422+
ServletContextInitializerBeans initializerBeans, String name) {
423+
return initializerBeans.stream()
424+
.filter(ServletRegistrationBean.class::isInstance)
425+
.map(ServletRegistrationBean.class::cast)
426+
.filter((r) -> name.equals(r.getServletName()))
427+
.findFirst()
428+
.orElse(null);
429+
}
483430

484431
}

0 commit comments

Comments
 (0)