I am trying to set a Spring Boot applications context root programmatically. The reason for the context root is we want the app to be accessed from localhost:port/{app_name}
and have all the controller paths append to it.
Here is the application configuration file for the web-app.
@Configuration public class ApplicationConfiguration { Logger logger = LoggerFactory.getLogger(ApplicationConfiguration.class); @Value("${mainstay.web.port:12378}") private String port; @Value("${mainstay.web.context:/mainstay}") private String context; private Set<ErrorPage> pageHandlers; @PostConstruct private void init(){ pageHandlers = new HashSet<ErrorPage>(); pageHandlers.add(new ErrorPage(HttpStatus.NOT_FOUND,"/notfound.html")); pageHandlers.add(new ErrorPage(HttpStatus.FORBIDDEN,"/forbidden.html")); } @Bean public EmbeddedServletContainerFactory servletContainer(){ TomcatEmbeddedServletContainerFactory factory = new TomcatEmbeddedServletContainerFactory(); logger.info("Setting custom configuration for Mainstay:"); logger.info("Setting port to {}",port); logger.info("Setting context to {}",context); factory.setPort(Integer.valueOf(port)); factory.setContextPath(context); factory.setErrorPages(pageHandlers); return factory; } public String getPort() { return port; } public void setPort(String port) { this.port = port; } }
Here is the index controller for the main page.
@Controller public class IndexController { Logger logger = LoggerFactory.getLogger(IndexController.class); @RequestMapping("/") public String index(Model model){ logger.info("Setting index page title to Mainstay - Web"); model.addAttribute("title","Mainstay - Web"); return "index"; } }
The new root of the application should be at localhost:12378/mainstay
, but it is still located at localhost:12378
.
What am I missing that is causing Spring Boot to not append the context root before the request mapping?
Advertisement
Answer
Why are you trying to roll your own solution. Spring-boot already supports that.
If you don’t already have one, add an application.properties
file to srcmainresources
. In that properties file, add 2 properties:
server.contextPath=/mainstay server.port=12378
UPDATE (Spring Boot 2.0)
As of Spring Boot 2.0 (due to the support of both Spring MVC and Spring WebFlux) the contextPath
has been changed to the following:
server.servlet.context-path=/mainstay
You can then remove your configuration for the custom servlet container. If you need to do some post processing on the container you can add a EmbeddedServletContainerCustomizer
implementation to your configuration (for instance to add the error pages).
Basically the properties inside the application.properties
serve as a default you can always override them by using another application.properties
next to the artifact you deliver or by adding JVM parameters (-Dserver.port=6666
).
See also The Reference Guide especially the properties section.
The class ServerProperties
implements the EmbeddedServletContainerCustomizer
. The default for contextPath
is ""
. In your code sample you are setting the contextPath
directly on the TomcatEmbeddedServletContainerFactory
. Next the ServerProperties
instance will process this instance and reset it from your path to ""
. (This line does a null
check but as the default is ""
it always fail and set the context to ""
and thus overriding yours).