How to Seamlessly Migrate a Spring Boot 3.0 App from HTTP to HTTPS
This comprehensive guide walks you through migrating a Spring Boot 3.0 JavaWeb application from HTTP to HTTPS, covering certificate acquisition (including Let’s Encrypt), conversion to Java keystore, Spring Boot and reverse‑proxy configuration, application adjustments, automated renewal, testing, rollback, and ongoing monitoring.
Overview
This guide details all steps required to migrate a Spring Boot 3.0 JavaWeb application from HTTP to HTTPS, including certificate acquisition, configuration changes, redirection setup, and ongoing maintenance.
1. Certificate Preparation and Management
1.1 Certificate Options
Let's Encrypt (free) : Free, automated, 90‑day validity; suitable for most small‑to‑medium sites.
Commercial certificate : Longer validity, higher trust, paid; ideal for enterprise applications.
Self‑signed certificate : Immediate and free but browsers show warnings; only for development/testing.
1.2 Using Let’s Encrypt (recommended)
# Install Certbot
sudo apt update
sudo apt install certbot
# Obtain certificate (standalone mode)
sudo certbot certonly --standalone -d yourdomain.com -d www.yourdomain.com
# Or webroot mode (if Nginx/Apache is running)
sudo certbot certonly --webroot -w /path/to/your/webroot -d yourdomain.com -d www.yourdomain.comThe certificates are stored in /etc/letsencrypt/live/yourdomain.com/ and include: fullchain.pem: certificate chain file privkey.pem: private key file cert.pem: certificate file chain.pem: intermediate certificate file
1.3 Convert certificate to Java Keystore
# Convert PEM to PKCS12
openssl pkcs12 -export -in fullchain.pem -inkey privkey.pem -out keystore.p12 -name tomcat -CAfile chain.pem -caname root
# Convert PKCS12 to JKS (if needed)
keytool -importkeystore -deststorepass changeit -destkeypass changeit -destkeystore keystore.jks -srckeystore keystore.p12 -srcstoretype PKCS12 -srcstorepass changeit -alias tomcat2. Spring Boot Application Configuration
2.1 application.properties / YAML
# HTTPS configuration (properties)
server.port=8443
server.ssl.enabled=true
server.ssl.key-store-type=PKCS12
server.ssl.key-store=classpath:keystore.p12
server.ssl.key-store-password=your_password
server.ssl.key-alias=tomcat
# Optional HTTP redirect port
server.http.port=8080 # HTTPS configuration (YAML)
server:
port: 8443
ssl:
enabled: true
key-store-type: PKCS12
key-store: classpath:keystore.p12
key-store-password: your_password
key-alias: tomcat
http:
port: 80802.2 Programmatic HTTPS redirection
@Configuration
@EnableWebSecurity
public class HttpsRedirectConfig {
// Redirect all HTTP requests to HTTPS
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.requiresChannel(channel -> channel.anyRequest().requiresSecure())
.authorizeHttpRequests(auth -> auth.anyRequest().permitAll());
return http.build();
}
// Enable both HTTP and HTTPS in embedded Tomcat
@Bean
public ServletWebServerFactory servletContainer() {
TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory();
tomcat.addAdditionalTomcatConnectors(createHttpConnector());
return tomcat;
}
private Connector createHttpConnector() {
Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
connector.setScheme("http");
connector.setPort(8080);
connector.setSecure(false);
connector.setRedirectPort(8443);
return connector;
}
}3. Web Server Configuration (Reverse Proxy)
3.1 Nginx example
server {
listen 80;
server_name yourdomain.com www.yourdomain.com;
# Redirect all HTTP to HTTPS
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name yourdomain.com www.yourdomain.com;
ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;
# SSL optimizations
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512;
ssl_prefer_server_ciphers off;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
# Security headers
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
# Proxy to Spring Boot
location / {
proxy_pass http://localhost:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# Certbot renewal challenge
location ~ /.well-known {
allow all;
}
}3.2 Apache example
<VirtualHost *:80>
ServerName yourdomain.com
ServerAlias www.yourdomain.com
Redirect permanent / https://yourdomain.com/
</VirtualHost>
<VirtualHost *:443>
ServerName yourdomain.com
ServerAlias www.yourdomain.com
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/yourdomain.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/yourdomain.com/privkey.pem
# Security headers
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
Header always set X-Frame-Options DENY
Header always set X-Content-Type-Options nosniff
# Proxy to Spring Boot
ProxyPreserveHost On
ProxyPass / http://localhost:8080/
ProxyPassReverse / http://localhost:8080/
RequestHeader set X-Forwarded-Proto "https"
</VirtualHost>4. Application‑Level Adjustments
4.1 Ensure the application handles HTTPS correctly
@Configuration
public class WebConfig implements WebMvcConfigurer {
// Force generated URLs to use HTTPS
@Bean
public FilterRegistrationBean<ForwardedHeaderFilter> forwardedHeaderFilter() {
FilterRegistrationBean<ForwardedHeaderFilter> registration = new FilterRegistrationBean<>();
registration.setFilter(new ForwardedHeaderFilter());
registration.addUrlPatterns("/*");
return registration;
}
}4.2 Update absolute URL references
// Use relative paths or a configured base URL
@Value("${app.baseUrl}")
private String baseUrl;
public String generateAbsoluteUrl(String path) {
return baseUrl + path;
}5. Certificate Auto‑Renewal
5.1 Set up Certbot automatic renewal
# Test renewal
sudo certbot renew --dry-run
# Add cron job (run daily at 2 AM)
0 2 * * * /usr/bin/certbot renew --quiet --post-hook "systemctl reload nginx"5.2 Reload configuration after renewal
#!/bin/bash
# /etc/letsencrypt/renewal-hooks/post/reload-springboot.sh
# Convert new certificate to PKCS12
openssl pkcs12 -export -in /etc/letsencrypt/live/yourdomain.com/fullchain.pem \
-inkey /etc/letsencrypt/live/yourdomain.com/privkey.pem \
-out /path/to/keystore.p12 -name tomcat -password pass:your_password
# Restart Spring Boot service
systemctl restart your-springboot-service6. Testing and Verification
6.1 OpenSSL test
# Test SSL connection
openssl s_client -connect yourdomain.com:443 -servername yourdomain.com
# Inspect certificate details
openssl x509 -in /path/to/cert.pem -text -noout6.2 Online SSL testing tools
SSL Labs SSL Test
Qualys SSL Server Test
HTTP Security Headers Check
6.3 Application health check
@RestController
public class HealthController {
@GetMapping("/health")
public ResponseEntity<String> health() {
return ResponseEntity.ok("Application is healthy over HTTPS!");
}
}7. Rollback Plan
Restore original application.properties configuration.
If a reverse proxy is used, revert Nginx/Apache settings.
Restart the application and web server.
Update DNS records if necessary.
8. Monitoring and Maintenance
8.1 Certificate expiration monitoring
# Check certificate expiration date
openssl x509 -enddate -noout -in /etc/letsencrypt/live/yourdomain.com/cert.pem
# Use monitoring tools such as Nagios, Zabbix, or Prometheus to alert before expiry.8.2 Log monitoring
# Enable SSL‑related logs in Spring Boot
logging.level.org.apache.tomcat.util.net=INFO
logging.level.org.apache.coyote=INFOConclusion
Migrating a Spring Boot 3.0 application from HTTP to HTTPS involves obtaining and configuring an SSL certificate, updating Spring Boot settings, configuring the reverse‑proxy server, adjusting application code, automating certificate renewal, thorough testing, and establishing monitoring to ensure a secure and reliable deployment.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Selected Java Interview Questions
A professional Java tech channel sharing common knowledge to help developers fill gaps. Follow us!
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.
