Master Spring Boot Web Server Configuration: Switch Servers, Ports, SSL, and More
This guide explains how to switch the embedded web server in Spring Boot 3.2.5, disable it, customize ports (including random and range ports), enable HTTP compression, configure SSL and HTTP/2, add servlets, filters, listeners, set up logging, and fine‑tune Tomcat and Undertow settings, all with practical code examples.
1. Switch Other Web Server
For servlet‑stack applications, spring-boot-starter-web includes Tomcat via spring-boot-starter-tomcat , but you can replace it with spring-boot-starter-jetty or spring-boot-starter-undertow . For reactive‑stack applications, spring-boot-starter-webflux brings in Reactor Netty, yet Tomcat, Jetty, or Undertow can also be used. Replace the default dependency with the desired one; Spring Boot provides a separate starter for each supported HTTP server.
<code><dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<!-- Exclude Tomcat dependency -->
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- Use Jetty instead -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency></code>Note: After switching the web server, adjust the corresponding settings in application.yml .
2. Disable Web Server
If the classpath contains the components required to start a web server, Spring Boot will start it automatically. To disable this behavior, set web-application-type to "none" in application.yml (or application.properties ).
<code>spring:
main:
web-application-type: "none"</code>This prevents the creation of any web‑server‑related beans when the ApplicationContext is instantiated.
3. Change Server Port
The default port is 8080. You can change it with server.port in application.properties , as a system property, or via the environment variable SERVER_PORT . Setting server.port=-1 disables HTTP endpoints while still creating a WebApplicationContext , which is useful for testing.
4. Random Port Allocation
Use server.port=0 to let the OS assign a free port. You can also specify a random port within a range:
<code>server:
port: ${random.int[5000,10000]}</code>This selects a port between 5000 and 10000.
5. Retrieve HTTP Port at Runtime
Define a bean that implements ApplicationListener<WebServerInitializedEvent> to capture the actual port:
<code>@Component
public class PackWebServerListener implements ApplicationListener<WebServerInitializedEvent> {
@Override
public void onApplicationEvent(WebServerInitializedEvent event) {
System.out.printf("Service running on port: %d%n", event.getWebServer().getPort());
}
}</code>In tests, @LocalServerPort can inject the real port when using @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) .
<code>@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
public class MyWebIntegrationTests {
@LocalServerPort
int port;
}</code>@LocalServerPort is a meta‑annotation for @Value("${local.server.port}") . It should only be used in test code, not in regular application code.
6. Enable HTTP Response Compression
Jetty, Tomcat, Reactor Netty, and Undertow support response compression. Enable it in application.properties :
<code>server:
compression:
enabled: true</code>By default, the response must be at least 2048 bytes; you can lower this threshold:
<code>server:
compression:
min-response-size: 1024</code>Compression applies to the following MIME types by default:
text/html
text/xml
text/plain
text/css
text/javascript
application/javascript
application/json
application/xml
You can customize the list with server.compression.mime-types .
7. Configure SSL
Set server.ssl.* properties in application.yml or application.properties . Example using a Java KeyStore:
<code>server:
port: 8443
ssl:
key-store: "classpath:pack.keystore"
key-store-password: "xxxooo"
key-password: "xxxooo"</code>Generate the keystore with:
<code>keytool -genkey -alias pack -keyalg RSA -keystore f:/pack.keystore</code>Note: Enabling SSL disables the plain HTTP 8080 connector; Spring Boot does not allow configuring both HTTP and HTTPS connectors simultaneously via properties.
8. Configure HTTP/2
Enable HTTP/2 with server.http2.enabled=true . Both h2 (over TLS) and h2c (cleartext) are supported. h2 requires SSL; without SSL, h2c is used, which is useful behind TLS‑terminating proxies.
9. General Web Server Configuration
Most server‑specific settings are available under the server.* namespace (e.g., server.tomcat.* , server.jetty.* ). If a needed option is missing, you can customize the server programmatically.
<code>@Component
public class PackTomcatWebServerCustomizer implements WebServerFactoryCustomizer<TomcatServletWebServerFactory> {
@Override
public void customize(TomcatServletWebServerFactory factory) {
// TODO: add custom Tomcat configuration
}
}</code>10. Add Servlet, Filter, or Listener
In servlet‑stack applications you can register Servlet , Filter , and Listener beans directly, or use registration beans:
<code>@Bean
public FilterRegistrationBean<CustomFilter> registration(CustomFilter filter) {
FilterRegistrationBean<CustomFilter> registration = new FilterRegistrationBean<>(filter);
registration.setUrlPatterns(Arrays.asList("/**"));
return registration;
}</code>Alternatively, use annotations @WebServlet , @WebFilter , @WebListener together with @ServletComponentScan .
11. Log Configuration
Access logs can be configured per server:
<code># Tomcat
server:
tomcat:
basedir: "my-tomcat"
accesslog:
enabled: true
pattern: "%t %a %r %s (%D microseconds)"
# Undertow
server:
undertow:
accesslog:
enabled: true
pattern: "%t %a %r %s (%D milliseconds)"
options:
server:
record-request-start-time: true
# Jetty
server:
jetty:
accesslog:
enabled: true
filename: "/var/log/jetty-access.log"
</code>Logs are written relative to the application’s working directory; you can change the directory with server.undertow.accesslog.dir .
12. Custom Tomcat Proxy Configuration
When using Tomcat, you can customize the header names that carry forwarding information:
<code>server:
tomcat:
remoteip:
remote-ip-header: "x-your-remote-ip-header"
protocol-header: "x-your-protocol-header"
</code>You can also define trusted internal proxies via server.tomcat.remoteip.internal-proxies .
13. Register Multiple Tomcat Connectors
<code>@Configuration(proxyBeanMethods = false)
public class MyTomcatConfiguration {
@Bean
public WebServerFactoryCustomizer<TomcatServletWebServerFactory> connectorCustomizer() {
return tomcat -> tomcat.addAdditionalTomcatConnectors(createConnector());
}
private Connector createConnector() {
Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
connector.setPort(8081);
return connector;
}
}</code>This opens an additional port (8081).
14. Enable Tomcat MBean Registry
<code>server:
tomcat:
mbeanregistry:
enabled: true</code>15. Undertow Multiple Listeners
<code>@Configuration(proxyBeanMethods = false)
public class MyUndertowConfiguration {
@Bean
public WebServerFactoryCustomizer<UndertowServletWebServerFactory> undertowListenerCustomizer() {
return factory -> factory.addBuilderCustomizers(this::addHttpListener);
}
private Builder addHttpListener(Builder builder) {
return builder.addHttpListener(8080, "0.0.0.0");
}
}</code>16. Use @ServerEndpoint for WebSocket
When using @ServerEndpoint in an embedded Spring Boot container, declare a ServerEndpointExporter bean:
<code>@Configuration(proxyBeanMethods = false)
public class MyWebSocketConfiguration {
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}</code>Spring Full-Stack Practical Cases
Full-stack Java development with Vue 2/3 front-end suite; hands-on examples and source code analysis for Spring, Spring Boot 2/3, and Spring Cloud.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.