Starter for building web, including RESTful, applications using Spring MVC with embedded Tomcat server.
—
Configure and customize the embedded web server (Tomcat, Jetty, or Undertow) for Spring Boot applications.
Choose and configure different embedded servers.
// Default: Tomcat (included in spring-boot-starter-web)
implementation 'org.springframework.boot:spring-boot-starter-web'
// Switch to Jetty
implementation('org.springframework.boot:spring-boot-starter-web') {
exclude group: 'org.springframework.boot', module: 'spring-boot-starter-tomcat'
}
implementation 'org.springframework.boot:spring-boot-starter-jetty'
// Switch to Undertow
implementation('org.springframework.boot:spring-boot-starter-web') {
exclude group: 'org.springframework.boot', module: 'spring-boot-starter-tomcat'
}
implementation 'org.springframework.boot:spring-boot-starter-undertow'Programmatically customize the embedded server factory.
/**
* Tomcat server customization
*/
@Bean
public WebServerFactoryCustomizer<TomcatServletWebServerFactory> tomcatCustomizer() {
return factory -> {
factory.setPort(9090);
factory.setContextPath("/api");
factory.setDisplayName("My Application");
// Connector customization
factory.addConnectorCustomizers(connector -> {
connector.setPort(8443);
connector.setScheme("https");
connector.setSecure(true);
connector.setMaxPostSize(50 * 1024 * 1024); // 50MB
});
// Additional customization
factory.addAdditionalTomcatConnectors(createSslConnector());
};
}
/**
* Jetty server customization
*/
@Bean
public WebServerFactoryCustomizer<JettyServletWebServerFactory> jettyCustomizer() {
return factory -> {
factory.setPort(8081);
factory.setContextPath("/app");
factory.addServerCustomizers(server -> {
// Jetty server customization
server.setStopTimeout(5000);
});
};
}
/**
* Undertow server customization
*/
@Bean
public WebServerFactoryCustomizer<UndertowServletWebServerFactory> undertowCustomizer() {
return factory -> {
factory.setPort(8082);
factory.addBuilderCustomizers(builder -> {
builder.addHttpListener(8080, "0.0.0.0");
builder.setBufferSize(1024);
builder.setDirectBuffers(true);
});
};
}Configure SSL/TLS for secure connections.
/**
* SSL configuration via properties
*/
@ConfigurationProperties("server.ssl")
public class SslProperties {
private boolean enabled = false;
private String keyStore;
private String keyStorePassword;
private String keyStoreType = "JKS";
private String keyAlias;
private String trustStore;
private String trustStorePassword;
private String protocol = "TLS";
private String[] enabledProtocols;
private String[] ciphers;
private ClientAuth clientAuth = ClientAuth.NONE;
public enum ClientAuth { NONE, WANT, NEED }
}
/**
* Programmatic SSL configuration
*/
@Bean
public ServletWebServerFactory servletContainer() {
TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory();
tomcat.addAdditionalTomcatConnectors(createSSLConnector());
return tomcat;
}
private Connector createSSLConnector() {
Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
Http11NioProtocol protocol = (Http11NioProtocol) connector.getProtocolHandler();
connector.setScheme("https");
connector.setSecure(true);
connector.setPort(8443);
protocol.setSSLEnabled(true);
protocol.setKeystoreFile("classpath:keystore.p12");
protocol.setKeystorePass("changeit");
protocol.setKeystoreType("PKCS12");
protocol.setKeyAlias("tomcat");
return connector;
}Configure server thread pools and connection handling.
# Tomcat thread configuration
server.tomcat.threads.max=200
server.tomcat.threads.min-spare=10
server.tomcat.accept-count=100
server.tomcat.max-connections=8192/**
* Custom thread pool configuration
*/
@Bean
public WebServerFactoryCustomizer<TomcatServletWebServerFactory> threadPoolCustomizer() {
return factory -> {
factory.addConnectorCustomizers(connector -> {
Http11NioProtocol protocol = (Http11NioProtocol) connector.getProtocolHandler();
protocol.setMaxThreads(300);
protocol.setMinSpareThreads(20);
protocol.setAcceptCount(150);
protocol.setMaxConnections(10000);
protocol.setConnectionTimeout(30000);
});
};
}Configure server access logging.
# Tomcat access log configuration
server.tomcat.accesslog.enabled=true
server.tomcat.accesslog.directory=logs
server.tomcat.accesslog.file-date-format=.yyyy-MM-dd
server.tomcat.accesslog.pattern=common
server.tomcat.accesslog.prefix=access_log
server.tomcat.accesslog.suffix=.log
server.tomcat.accesslog.rotate=true/**
* Programmatic access log configuration
*/
@Bean
public WebServerFactoryCustomizer<TomcatServletWebServerFactory> accessLogCustomizer() {
return factory -> {
factory.addEngineValves(new AccessLogValve() {{
setEnabled(true);
setDirectory("logs");
setPrefix("access_log");
setSuffix(".log");
setPattern("common");
setFileDateFormat(".yyyy-MM-dd");
}});
};
}Configure multiple connectors for different protocols or ports.
/**
* HTTP and HTTPS connectors
*/
@Bean
public ServletWebServerFactory servletContainer() {
TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory();
// Add HTTP connector
tomcat.addAdditionalTomcatConnectors(createHttpConnector());
// Add HTTPS connector
tomcat.addAdditionalTomcatConnectors(createHttpsConnector());
return tomcat;
}
private Connector createHttpConnector() {
Connector connector = new Connector(TomcatServletWebServerFactory.DEFAULT_PROTOCOL);
connector.setPort(8080);
connector.setScheme("http");
connector.setSecure(false);
return connector;
}
private Connector createHttpsConnector() {
Connector connector = new Connector(TomcatServletWebServerFactory.DEFAULT_PROTOCOL);
connector.setPort(8443);
connector.setScheme("https");
connector.setSecure(true);
Http11NioProtocol protocol = (Http11NioProtocol) connector.getProtocolHandler();
protocol.setSSLEnabled(true);
// SSL configuration...
return connector;
}Configure graceful server shutdown behavior.
# Graceful shutdown configuration
server.shutdown=GRACEFUL
spring.lifecycle.timeout-per-shutdown-phase=30s/**
* Graceful shutdown customization
*/
@Bean
public GracefulShutdown gracefulShutdown() {
return new GracefulShutdown();
}
@Component
public class GracefulShutdownHandler {
@EventListener
public void handleShutdown(ContextClosedEvent event) {
// Custom shutdown logic
log.info("Application is shutting down gracefully...");
}
}// Base servlet web server factory
public interface ServletWebServerFactory {
WebServer getWebServer(ServletContextInitializer... initializers);
}
// Tomcat server factory
public class TomcatServletWebServerFactory implements ServletWebServerFactory {
public void setPort(int port);
public void setContextPath(String contextPath);
public void setDisplayName(String displayName);
public void addConnectorCustomizers(TomcatConnectorCustomizer... customizers);
public void addAdditionalTomcatConnectors(Connector... connectors);
public void addEngineValves(Valve... valves);
}
// Jetty server factory
public class JettyServletWebServerFactory implements ServletWebServerFactory {
public void setPort(int port);
public void setContextPath(String contextPath);
public void addServerCustomizers(JettyServerCustomizer... customizers);
}
// Undertow server factory
public class UndertowServletWebServerFactory implements ServletWebServerFactory {
public void setPort(int port);
public void setContextPath(String contextPath);
public void addBuilderCustomizers(UndertowBuilderCustomizer... customizers);
public void addDeploymentInfoCustomizers(UndertowDeploymentInfoCustomizer... customizers);
}
// Web server factory customizer interface
@FunctionalInterface
public interface WebServerFactoryCustomizer<T extends WebServerFactory> {
void customize(T factory);
}Install with Tessl CLI
npx tessl i tessl/maven-org-springframework-boot--spring-boot-starter-web