spring-mvcspring-bootweb-architectureservlet-container

Web server with REST api - Spring Boot - Mulitple servlet containers


In my architecture, I am using spring as both a web server, serving static html and javascript pages, and as a rest api. Currently, my spring app listens on port 8080. Even though I can easily change it to port 80, I think the api and the web server should be on different ports, and see no reason to create a separate app just to serve static content, which spring can easily do.

I did look online and at some other questions, and found spring can listen on two different ports, using multiple servlet containers. Some question even said all one has to do is create multiple application context.

However, there was no mention on how to do so, which, at least for me, is not trivial, especially when using Spring Boot.

  1. How can I create multiple servlet containers or multiple application context, in order to listen on multiple ports (80 and 8080) ?
  2. After setting those up, how do I control which servlet does what? that is, which one serves the static pages, and which one serves the rest api?

-

EDIT

The following question seems to match my own, yet as previously mentioned, I do not know how to implement this, specially when using Spring Boot/Annotations, and not xml configuration.

Configure multiple servletcontainers/servlets with spring boot

EDIT (2)

A good use case for such a thing would be making your site ssl-enabled, yet not required. That is, you want to enable ssl over potr 443, yet enable users to use unsecure access through port 80.

EDIT (3)

I do not know if Dave Syer answer is the best one, but it seems to work. Note that unlike his method, I am using a servlet container customizer to change the port, but still i'm using a second thread and creating second spring application.

EDIT (Answer)

The original answer of Dave Syer is working, but it was not what I was looking for. As stated in one of his comments, the answer is to create a second Connector object if you're using Tomcat servlet container (default for spring), or Handler for jetty.

I used someting like the following:

public class App implements EmbeddedServletContainerCustomizer {
  public void customize(ConfigurableEmbeddedServletContainer container) {
    TomcatEmbeddedServletContainerFactory tombat = (TomcatEmbeddedServletContainerFactory)container;

    tomcat.addAditinoalTomcatConnectors(...);
  }
}

Solution

  • I still don't know why you want to do this (what's the advantage over just running a single container?), but you can easily run 2 servers using SpringApplication. Example using a background thread:

    new Thread(new Runnable() { public void run() {
        SpringApplication.run(StaticServer.class, "--server.port=${static.port:8081}");
    }}).start();
    SpringApplication.run(ApiServer.class, args);