Using multiple dispatcher servlets / web contexts with spring boot
Solution 1
As @josh-ghiloni already said, you need to register a ServletRegistrationBean
for every isolated web context you want to create.
You need to create an application context from a xml or java config class. You can use @Import
and @ComponentScan
annotation to add shared services to the parent context. Here is an example:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.context.embedded.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.context.support.XmlWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;
//@ComponentScan({"..."})
//@Import({})
public class Starter {
public static void main(String[] args) throws Exception {
SpringApplication.run(Starter.class, args);
}
@Bean
public ServletRegistrationBean apiV1() {
DispatcherServlet dispatcherServlet = new DispatcherServlet();
XmlWebApplicationContext applicationContext = new XmlWebApplicationContext();
applicationContext.setConfigLocation("classpath:/META-INF/spring/webmvc-context.xml");
dispatcherServlet.setApplicationContext(applicationContext);
ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(dispatcherServlet, "/api/1/*");
servletRegistrationBean.setName("api-v1");
return servletRegistrationBean;
}
@Bean
public ServletRegistrationBean apiV2() {
DispatcherServlet dispatcherServlet = new DispatcherServlet();
AnnotationConfigWebApplicationContext applicationContext = new AnnotationConfigWebApplicationContext();
applicationContext.register(ResourceConfig.class);
dispatcherServlet.setApplicationContext(applicationContext);
ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(dispatcherServlet, "/api/2/*");
servletRegistrationBean.setName("api-v2");
return servletRegistrationBean;
}
}
Solution 2
Create a ServletRegistrationBean
that declares the servlet and its mappings. You will probably also want to exclude DispatcherServletAutoConfiguration
from the autoconfigurations called, because it will register a DispatcherServlet
at /
and override yours
EDIT Despite my comment below saying you might not need this, unless you need your APIs running on separate ports (and it doesn't sound like you do), Dave Syer, one of the authors of Spring Boot, answered a very similar question here: Configure multiple servletcontainers/servlets with spring boot
Jan
Outdoor sport enthusiast and nerd. You too? Lets work together! http://www.komoot.de/jobs
Updated on January 03, 2021Comments
-
Jan over 3 years
I created a spring boot application with a parent context (services) and child context (spring-webmvc controllers):
@Configuration public class MainApiApplication { public static void main(String[] args) { new SpringApplicationBuilder() .parent(Services.class) .child(ApiOne.class, MainApiApplication.class) .run(args); } @Bean public EmbeddedServletContainerFactory servletContainer() { return new TomcatEmbeddedServletContainerFactory(); } }
Now I want to add another client context (and DispatcherServlet) for my
ApiTwo.class
configuration. I think I have to do two things:- Move the
servletContainer
(thus the MainApiApplication.class configuration) out of the child context and - add a path mapping
/one/ -> ApiOne.class
and/two/ ApiTwo.class
What is the spring boot way to do it?
- Move the