2

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(...);
  }
}
Community
  • 1
  • 1
saw
  • 165
  • 1
  • 11
  • To start a Spring Boot application context you generally would use `SpringApplication`. Why do you need to do that though? What problem would it solve? – Dave Syer Dec 22 '14 at 09:21
  • I'm not trying to do that, nor would it solve anything. Not sure how you got to it. As said, I am trying to create a _second_ application context, so I can listen on two different ports. – saw Dec 22 '14 at 15:06
  • Yeah, but how would you launch a second context (`SpringApplication`)? It's just not super clear why you need that. – Dave Syer Dec 22 '14 at 15:12
  • As far as I understand, SpringApplication creates context, but you can do it manually, hence creating a second one. Just not sure how. Also, look at this: http://stackoverflow.com/questions/21630820/configure-multiple-servletcontainers-servlets-with-spring-boot – saw Dec 22 '14 at 15:34
  • So is that a duplicate question and you have your answer in different words? – Dave Syer Dec 22 '14 at 16:51
  • no. The question I linked has the answer I want, but as said, I don'[t know how to implement the suggested answer, specially when using Spring Boot. – saw Dec 22 '14 at 17:20
  • It's trivial to start 2 apps (and the question you linked to has a reference to sample code). So a) I don't understand what's missing, and b) you haven't really said why you want to do it (if you did it might become more clear why it is your question and comments together don't yet make sense). – Dave Syer Dec 22 '14 at 22:12
  • b) I actually did say the reason, more than one time: to listen on multiple ports. That is, requests to rest api should be handled by port 8080, while requests to static content should be handled by port 80 a) The sample isn't clear on how to create a non-child-parent relationship context, nor how to make it listen on different port.. – saw Dec 22 '14 at 23:15

1 Answers1

0

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);
Dave Syer
  • 56,583
  • 10
  • 155
  • 143
  • I have edited my question, adding what in my opinion is a good use case for creating multiple servlet containers. Does your answer still apply? That is, is creating multiple spring applications still the right way (and will work) to do so? – saw Dec 23 '14 at 20:50
  • Like you said, it works. If you want to support SSL and plain HTTP in the same app you don't actually need 2 containers, though. And if you really have 2 apps, why do they need to be in the same JVM? – Dave Syer Dec 24 '14 at 08:08
  • I know I can create two separate JVMs, but why should I? creating two different processes, making sure each one is up.. not to mention I'll also need to separate much of the code, since i'll need to create different project (although I guess I could use a command line argument for that). Anyway, how would I support SSL and plain HTTP in the same app, with one container? I thought a container can only listen on one port.. – saw Dec 24 '14 at 14:42
  • Each container implementation is different but they all have APIs for adding additional ports. In Tomcat you add a `Connector`, and in Jersey I think it's called a `Handler`. – Dave Syer Dec 24 '14 at 17:17
  • That was what I was looking for! I can't believe it was simple.. Please edit your answer to indicate this was the desired result. I'll do so as well. – saw Dec 24 '14 at 20:11