Skip to content

Commit 7740938

Browse files
committed
Integration test each servlet web server with Spring MVC
1 parent 66ba1cd commit 7740938

File tree

8 files changed

+166
-71
lines changed

8 files changed

+166
-71
lines changed

spring-boot-project/spring-boot-jetty/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ dependencies {
3838
testRuntimeOnly("org.eclipse.jetty:jetty-client")
3939
testRuntimeOnly("org.eclipse.jetty.http2:jetty-http2-client")
4040
testRuntimeOnly("org.eclipse.jetty.http2:jetty-http2-client-transport")
41+
testRuntimeOnly("org.springframework:spring-webmvc")
4142
}
4243

4344
test {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/*
2+
* Copyright 2012-2025 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.jetty.servlet;
18+
19+
import org.springframework.boot.jetty.JettyWebServer;
20+
import org.springframework.boot.web.server.servlet.context.ServletWebServerApplicationContext;
21+
import org.springframework.boot.web.servlet.context.AbstractServletWebServerMvcIntegrationTests;
22+
import org.springframework.context.annotation.Bean;
23+
import org.springframework.context.annotation.Configuration;
24+
25+
/**
26+
* Integration tests for {@link ServletWebServerApplicationContext} and
27+
* {@link JettyWebServer} running Spring MVC.
28+
*/
29+
class JettyServletWebServerMvcIntegrationTests extends AbstractServletWebServerMvcIntegrationTests {
30+
31+
protected JettyServletWebServerMvcIntegrationTests() {
32+
super(JettyConfig.class);
33+
}
34+
35+
@Configuration(proxyBeanMethods = false)
36+
static class JettyConfig {
37+
38+
@Bean
39+
JettyServletWebServerFactory webServerFactory() {
40+
return new JettyServletWebServerFactory(0);
41+
}
42+
43+
}
44+
45+
}

spring-boot-project/spring-boot-tomcat/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ dependencies {
4141
testRuntimeOnly("org.eclipse.jetty:jetty-client")
4242
testRuntimeOnly("org.eclipse.jetty.http2:jetty-http2-client")
4343
testRuntimeOnly("org.eclipse.jetty.http2:jetty-http2-client-transport")
44+
testRuntimeOnly("org.springframework:spring-webmvc")
4445

4546
tomcatDistribution("org.apache.tomcat:tomcat:${tomcatVersion}@zip")
4647
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/*
2+
* Copyright 2012-2025 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.tomcat.servlet;
18+
19+
import org.springframework.boot.tomcat.TomcatWebServer;
20+
import org.springframework.boot.web.server.servlet.context.ServletWebServerApplicationContext;
21+
import org.springframework.boot.web.servlet.context.AbstractServletWebServerMvcIntegrationTests;
22+
import org.springframework.context.annotation.Bean;
23+
import org.springframework.context.annotation.Configuration;
24+
25+
/**
26+
* Integration tests for {@link ServletWebServerApplicationContext} and
27+
* {@link TomcatWebServer} running Spring MVC.
28+
*/
29+
class TomcatServletWebServerMvcIntegrationTests extends AbstractServletWebServerMvcIntegrationTests {
30+
31+
protected TomcatServletWebServerMvcIntegrationTests() {
32+
super(TomcatConfig.class);
33+
}
34+
35+
@Configuration(proxyBeanMethods = false)
36+
static class TomcatConfig {
37+
38+
@Bean
39+
TomcatServletWebServerFactory webServerFactory() {
40+
return new TomcatServletWebServerFactory(0);
41+
}
42+
43+
}
44+
45+
}

spring-boot-project/spring-boot-undertow/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ dependencies {
3434
testRuntimeOnly("org.eclipse.jetty:jetty-client")
3535
testRuntimeOnly("org.eclipse.jetty.http2:jetty-http2-client")
3636
testRuntimeOnly("org.eclipse.jetty.http2:jetty-http2-client-transport")
37+
testRuntimeOnly("org.springframework:spring-webmvc")
3738
}
3839

3940
test {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/*
2+
* Copyright 2012-2025 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.undertow.servlet;
18+
19+
import org.springframework.boot.undertow.UndertowWebServer;
20+
import org.springframework.boot.web.server.servlet.context.ServletWebServerApplicationContext;
21+
import org.springframework.boot.web.servlet.context.AbstractServletWebServerMvcIntegrationTests;
22+
import org.springframework.context.annotation.Bean;
23+
import org.springframework.context.annotation.Configuration;
24+
25+
/**
26+
* Integration tests for {@link ServletWebServerApplicationContext} and
27+
* {@link UndertowWebServer} running Spring MVC.
28+
*/
29+
class UndertowServletWebServerMvcIntegrationTests extends AbstractServletWebServerMvcIntegrationTests {
30+
31+
protected UndertowServletWebServerMvcIntegrationTests() {
32+
super(UndertowConfig.class);
33+
}
34+
35+
@Configuration(proxyBeanMethods = false)
36+
static class UndertowConfig {
37+
38+
@Bean
39+
UndertowServletWebServerFactory webServerFactory() {
40+
return new UndertowServletWebServerFactory(0);
41+
}
42+
43+
}
44+
45+
}

spring-boot-project/spring-boot-web-server/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ dependencies {
3131
testFixturesCompileOnly("org.mockito:mockito-core")
3232
testFixturesCompileOnly("org.springframework:spring-tx")
3333
testFixturesCompileOnly("org.springframework:spring-webflux")
34+
testFixturesCompileOnly("org.springframework:spring-webmvc")
3435

3536
testImplementation(project(":spring-boot-project:spring-boot-test"))
3637
testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support"))
Lines changed: 27 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -21,19 +21,16 @@
2121
import org.junit.jupiter.api.AfterEach;
2222
import org.junit.jupiter.api.Test;
2323

24-
import org.springframework.boot.jetty.servlet.JettyServletWebServerFactory;
2524
import org.springframework.boot.testsupport.classpath.resources.WithResource;
26-
import org.springframework.boot.testsupport.web.servlet.DirtiesUrlFactories;
27-
import org.springframework.boot.tomcat.servlet.TomcatServletWebServerFactory;
28-
import org.springframework.boot.undertow.servlet.UndertowServletWebServerFactory;
2925
import org.springframework.boot.web.server.WebServer;
30-
import org.springframework.boot.web.server.servlet.ServletWebServerFactory;
26+
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
27+
import org.springframework.boot.web.server.WebServerFactoryCustomizerBeanPostProcessor;
28+
import org.springframework.boot.web.server.servlet.ConfigurableServletWebServerFactory;
3129
import org.springframework.boot.web.server.servlet.context.AnnotationConfigServletWebServerApplicationContext;
3230
import org.springframework.boot.web.server.servlet.context.ServletWebServerApplicationContext;
3331
import org.springframework.boot.web.servlet.ServletRegistrationBean;
3432
import org.springframework.context.annotation.Bean;
3533
import org.springframework.context.annotation.Configuration;
36-
import org.springframework.context.annotation.Import;
3734
import org.springframework.context.annotation.PropertySource;
3835
import org.springframework.core.env.Environment;
3936
import org.springframework.http.HttpMethod;
@@ -49,17 +46,22 @@
4946
import static org.assertj.core.api.Assertions.assertThat;
5047

5148
/**
52-
* Integration tests for {@link ServletWebServerApplicationContext} and {@link WebServer}s
53-
* running Spring MVC.
49+
* Base class for integration testing of {@link ServletWebServerApplicationContext} and
50+
* {@link WebServer}s running Spring MVC.
5451
*
5552
* @author Phillip Webb
5653
* @author Ivan Sopov
5754
*/
58-
@DirtiesUrlFactories
59-
class ServletWebServerMvcIntegrationTests {
55+
public abstract class AbstractServletWebServerMvcIntegrationTests {
6056

6157
private AnnotationConfigServletWebServerApplicationContext context;
6258

59+
private Class<?> webServerConfiguration;
60+
61+
protected AbstractServletWebServerMvcIntegrationTests(Class<?> webServerConfiguration) {
62+
this.webServerConfiguration = webServerConfiguration;
63+
}
64+
6365
@AfterEach
6466
void closeContext() {
6567
try {
@@ -71,27 +73,17 @@ void closeContext() {
7173
}
7274

7375
@Test
74-
void tomcat() throws Exception {
75-
this.context = new AnnotationConfigServletWebServerApplicationContext(TomcatConfig.class);
76-
doTest(this.context, "/hello");
77-
}
78-
79-
@Test
80-
void jetty() throws Exception {
81-
this.context = new AnnotationConfigServletWebServerApplicationContext(JettyConfig.class);
82-
doTest(this.context, "/hello");
83-
}
84-
85-
@Test
86-
void undertow() throws Exception {
87-
this.context = new AnnotationConfigServletWebServerApplicationContext(UndertowConfig.class);
76+
void basicConfig() throws Exception {
77+
this.context = new AnnotationConfigServletWebServerApplicationContext(this.webServerConfiguration,
78+
Config.class);
8879
doTest(this.context, "/hello");
8980
}
9081

9182
@Test
9283
@WithResource(name = "conf.properties", content = "context=/example")
9384
void advancedConfig() throws Exception {
94-
this.context = new AnnotationConfigServletWebServerApplicationContext(AdvancedConfig.class);
85+
this.context = new AnnotationConfigServletWebServerApplicationContext(this.webServerConfiguration,
86+
AdvancedConfig.class);
9587
doTest(this.context, "/example/spring/hello");
9688
}
9789

@@ -105,55 +97,13 @@ private void doTest(AnnotationConfigServletWebServerApplicationContext context,
10597
}
10698
}
10799

108-
// Simple main method for testing in a browser
109-
@SuppressWarnings("resource")
110-
static void main(String[] args) {
111-
new AnnotationConfigServletWebServerApplicationContext(JettyServletWebServerFactory.class, Config.class);
112-
}
113-
114-
@Configuration(proxyBeanMethods = false)
115-
@Import(Config.class)
116-
static class TomcatConfig {
117-
118-
@Bean
119-
ServletWebServerFactory webServerFactory() {
120-
return new TomcatServletWebServerFactory(0);
121-
}
122-
123-
}
124-
125-
@Configuration(proxyBeanMethods = false)
126-
@Import(Config.class)
127-
static class JettyConfig {
128-
129-
@Bean
130-
ServletWebServerFactory webServerFactory() {
131-
return new JettyServletWebServerFactory(0);
132-
}
133-
134-
}
135-
136-
@Configuration(proxyBeanMethods = false)
137-
@Import(Config.class)
138-
static class UndertowConfig {
139-
140-
@Bean
141-
ServletWebServerFactory webServerFactory() {
142-
return new UndertowServletWebServerFactory(0);
143-
}
144-
145-
}
146-
147100
@Configuration(proxyBeanMethods = false)
148101
@EnableWebMvc
149102
static class Config {
150103

151104
@Bean
152105
DispatcherServlet dispatcherServlet() {
153106
return new DispatcherServlet();
154-
// Alternatively you can use ServletContextInitializer beans including
155-
// ServletRegistration and FilterRegistration. Read the
156-
// EmbeddedWebApplicationContext Javadoc for details.
157107
}
158108

159109
@Bean
@@ -175,10 +125,16 @@ static class AdvancedConfig {
175125
}
176126

177127
@Bean
178-
ServletWebServerFactory webServerFactory() {
179-
JettyServletWebServerFactory factory = new JettyServletWebServerFactory(0);
180-
factory.setContextPath(this.env.getProperty("context"));
181-
return factory;
128+
static WebServerFactoryCustomizerBeanPostProcessor webServerFactoryCustomizerBeanPostProcessor() {
129+
return new WebServerFactoryCustomizerBeanPostProcessor();
130+
}
131+
132+
@Bean
133+
WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> contextPathCustomizer() {
134+
return (factory) -> {
135+
String contextPath = this.env.getProperty("context");
136+
factory.setContextPath(contextPath);
137+
};
182138
}
183139

184140
@Bean

0 commit comments

Comments
 (0)