Blog

How to add HTTPS to your Java web application

By  
Matti Tahvonen
Matti Tahvonen
·
On Aug 19, 2025 4:00:56 PM
·

HTTPS (aka HTTP over TLS aka HTTP over SSL) is no longer optional for web sites. Even if your application wouldn’t handle critical data that attackers would be interested in, or it would be only used within a secure intranet, modern browsers show a scary “Not secure” warning to users accessing servers with plain http.

Adding HTTPS to Your Java Web Application

Also, many essential web features like Geolocation API and Service Workers require it, and many identity providers and payment gateways refuse to call back to plain HTTP. Browsers also mandate TLS for all HTTP/2 connections. During the development you are most often fine when accessing local addresses (browsers treat localhost mostly as “secure context”), but for actual deployments, HTTPS has become pretty much mandatory.

By using a PaaS like service or other high level hosting solution like Vaadin Control Center, you get HTTPS connection out of the box, or it is just a matter of configuration. Otherwise, for an engineer who has picked up a high level web framework like Vaadin, setting up the HTTPS connection might sound like a heavy struggle. The good news is: setting up a correctly, auto‑renewing TLS setup is not that hard these days, in case you take the right path of dozens of options—even if you don’t consider yourself a “web ops” person.

Use a properly signed certificate!

In addition to securing the data transferred between the browsers and the servers, TLS uses digital certificates to prove that you are talking to a certain server. Unless the certificate is signed by a trusted “root certificate” (operating systems ship with a bunch of these), your browser will show a nasty looking warning before letting users enter the site. You can obtain your certificate from a certificate authority with varying degrees of pricing and validation. For many cases it is enough to have e.g. completely free of charge Let’s Encrypt certificate (a non-profit certificate authority that only makes an automated domain validation).

In case you are using a higher level PaaS like approach to host your application, such as Azure App Service, AWS Elastic Beanstalk or Heroku, there is a high chance that you get a certificate for your domain out of the box or it is just a matter of checking on the configuration. These services typically have a reverse proxy in front of your application server, that transparently secures the connection for you with a proper certificate. For additional trust, you might want to bring in your own certificate to these systems too.

Configure HTTPS connection in your reverse proxy

For a Java developer it may intuitively be tempting to configure TLS to your Java server, especially in a single-server setups. Even though I’m a big Java enthusiast myself, my primary tip is to avoid that and to delegate TLS connection to your reverse proxy (also referred often as load balancer or as front proxy as it sits in front of your application servers or ingress in K8s lingo). And if you don’t yet have a reverse-proxy, I suggest you consider one just for the sake of TLS. The same applies for application servers on other platforms.

While it is certainly possible to for example configure your Tomcat to directly handle the HTTPS connection, handling HTTPS connections is a very universal "problem". Handling HTTPS connections is exceptionally well optimized (setup simplicity, performance and instructions) in generic web servers (Apache, nginx, that are often used as reverse proxies) and in specifically designed proxy servers like HAProxy. There is also a high chance that the reverse proxy helps you in the future as well, in case you for example need load balancing or want to implement certain services using another language or application server.

In this kind of setup the connection between the proxy and the app servers can be left on plain http, as that traffic happens within a trusted network. Maintaining the certificates can thus happen only in a single place, even if you would have a cluster of application servers powering your web application.

The optimal setup naturally depends on your hosting setup. For example with many PaaS-like solutions you get this kind of setup out of the box, with pure K8s you’ll configure your ingress, with Vaadin Control Center you can go with its helpful built-in tooling. 

As a recipe for more traditional server setup, I can share my trivial configuration of one pro-bono service I'm hosting with a single cheap virtual server:

  1. Installed standard Ubuntu Server on a cheap virtual machine
  2. Configured my DNS name to point to the public IP address of it
  3. Installed nginx and used the Certbot tooling to install Let's Encrypt certificate. These instructions are easy even if you are not a professional server maintainer. This approach also gives you good defaults like re-directing non-https connections to https port. The good thing about the default installation is that it configures automatic renewal with a cron jog. Let’s Encrypt certificates have fairly short lifespans!
  4. Installed the Spring Boot based Vaadin web app as a service on 8080 port (not opened for public).
  5. Configured nginx to serve static files and act as a reverse proxy. In case it doesn’t find an exactly matching file for the request, it passes the request to the application server. In practice every request goes to the application server, but I am kind of prepared to possibly host static files directly from the nginx. Below is the relevant part of my nginx configuration ((snippet from /etc/nginx/sites-available/default)), that is within the server configuration that handles https connections :
```nginx.conf
location / {
   # First attempt to serve a file, then pass to appserver
   try_files $uri @proxy;
}
location @proxy {
    proxy_pass  http://localhost:8080;
}
```

In my nginx setup, there are also some extra configs to finetune web sockets connections and custom headers for the app server to e.g. know the real user ip address, but those are irrelevant regarding https setup. 

When and how to configure HTTPS to your Java server?

So when does it make sense to configure TLS directly on your Java server or application? While I still recommend the approach I mentioned earlier, there are a couple of reasons why you might choose to do so:

  • You are delivering your application as a single binary/jar file
  • You are aiming to minimize all natively compiled parts from your system. Write once, run anywhere!
  • For other architectural or organizational reasons you wish to keep as much as possible in Java/JVM
  • You need it for testing purposes, but something prevents you from dropping a separate front proxy (server or process) to the equation
  • You need TLS also for the connection between your reverse proxy and application server
  • You can’t take the negligible performance penalty of the separate front-proxy process

Due to the diverse Java ecosystem, you should most likely refer to your application servers or frameworks docs for more specific instructions. Handling and configuring certificates with Java servers has traditionally involved using the JDKs built-in keytool and JVM specific keystore files (JKS). As Java specific tools these are often not documented well in certificate authority's instructions or tooling. 

Luckily recent versions of Java tooling, servlet containers and frameworks, like Quarkus and Spring Boot, have improved their support towards more standard certificate formats and made other configurability improvements. For example Spring Boot 3.1 introduced a concept called SSL bundles for further convenience and Quarkus even has a built-in Let's Encrypt support (disclaimer: I have not tried either of these new features).

Once you have your application specific setup ready, remember to automate renewing of certificates as well as possible!

Matti Tahvonen
Matti Tahvonen
Matti Tahvonen has a long history in Vaadin R&D: developing the core framework from the dark ages of pure JS client side to the GWT era and creating number of official and unofficial Vaadin add-ons. His current responsibility is to keep you up to date with latest and greatest Vaadin related technologies. You can follow him on Twitter – @MattiTahvonen
Other posts by Matti Tahvonen