Add context path to Spring Boot application
Asked Answered
I

22

235

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?

Isoelectronic answered 5/12, 2013 at 16:33 Comment(1)
The video explains how to set context path in spring boot youtube.com/watch?v=7HqtH3L9erESquarrose
R
480

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 src\main\resources. 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).

Ratcliffe answered 6/12, 2013 at 7:29 Comment(6)
Altough your answer is correct (I mean, you can customize the servlet container properties by the the application properties file), why is there a setContextPath(path) method, I mean, if the path is not enforced, what is it good for? BTW, same goes for the setContextPath(...) on the EmbeddedServletContainerCustomizerCristobalcristobalite
I would expect the one from EmbeddedServletContainerCustomizer to also work. But I would go what is provided instead of trying to bolt on your own. Why your solution doesn't work has to do with the default behavior programmed (accidentally?) in the ServerProperties, the default configured contextPath is "" (and it checks for null and not "". The latter overrides your explicitly set contextPath.Ratcliffe
The properties have changed, see my answer below.Dink
I guess the property in Spring Boot 2.0 is "server.servlet.context-path"Aliphatic
Maybe helpful for someone: for context-path to work, spring boot project must be a web-project. <artifactId>spring-boot-starter-web</artifactId> must be added as dependencyAscites
can we have an update on this answer for spring boot 3 @M.DeinumBelgium
S
42

If you are using Spring Boot, then you don't have to configure the server properties via Bean initializing.

Instead, if one functionality is available for basic configuration, then it can be set in a "properties" file called application, which should reside under src\main\resources in your application structure. The "properties" file is available in two formats

  1. .yml

  2. .properties

The way you specify or set the configurations differs from one format to the other.

In your specific case, if you decide to use the extension .properties, then you would have a file called application.properties under src\main\resources with the following configuration settings

server.port = 8080
server.contextPath = /context-path

OTOH, if you decide to use the .yml extension (i.e. application.yml), you would need to set the configurations using the following format (i.e. YAML):

server:
    port: 8080
    contextPath: /context-path

For more common properties of Spring Boot refer to the link below:

https://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html

Suppositious answered 9/2, 2016 at 14:34 Comment(0)
W
30

If you use Spring Boot 2.0.0 use:

server.servlet.context-path
Whodunit answered 13/5, 2017 at 12:16 Comment(6)
this doesn't work for war files deployed in external tomcatGratify
For me this didn't worked (Spring Boot 2.1.2), but did worked this: server.servlet.contextPath=/apiErrecart
@pise, did you know how to fix it for war file in external tomcat?Stevenstevena
@Stevenstevena if you deploy WAR file to external tomcat, you've to rename the WAR file to ROOT.war to make thing work as expected.Sandlin
@DucLe in my case I just rename war file to needed path. I.e. servicename#api, where # is replaced by / by tomcat.Stevenstevena
I wish they would stop changing the property nameStoneblind
A
16

please note that the "server.context-path" or "server.servlet.context-path" [starting from springboot 2.0.x] properties will only work if you are deploying to an embedded container e.g., embedded tomcat. These properties will have no effect if you are deploying your application as a war to an external tomcat for example.

see this answer here: https://mcmap.net/q/119592/-changing-the-context-path-of-deployed-spring-boot-war-on-a-container-tomcat-server-so-it-is-not-demo-0-01-snapshot

Alimony answered 2/8, 2018 at 14:47 Comment(4)
Has anyone figured out how to configure this when deploying to an external tomcat as war file using springboot v2.x and tomcat v8.5?Alberich
@Alimony even I looking for the answer, what if we are deploying the war file in external tomcat how to set context path.Gratify
I was trying it out. It's exactly like what it was stated in the link above. Change the build -> finalName attribute value to your context path. The resulting war file will then be using the context path as the filename, which will then be used by tomcat to serve as the context path.Bird
the only way i can think of for deploying as war in external tomcat is to ensure the war name matches the context you are after. so for example, if you want the context to be '/xyzwebapp' then your war must be named xyzwebapp.war. to achieve this, you can add the following to the <build> element in your pom.xml : <finalName>xyzwebapp</finalName>.Alimony
D
11

The correct properties are

server.servlet.path

to configure the path of the DispatcherServlet

and

server.servlet.context-path

to configure the path of the applications context below that.

Dink answered 24/4, 2017 at 9:3 Comment(0)
S
6

If you're using spring-boot-starter-webflux use:

spring:
  webflux:
    base-path: /api

I swear to God... I forget this every single time.

Stoneblind answered 13/5, 2021 at 8:39 Comment(1)
THIS! is what i needed for a spring boot 2.7.5 with spring-boot-starter-webflux but without spring-boot-starter-webNucleate
S
5

You can do it by adding the port and contextpath easily to add the configuration in [src\main\resources] .properties file and also .yml file

application.porperties file configuration

server.port = 8084
server.contextPath = /context-path

application.yml file configuration

server:
port: 8084
contextPath: /context-path

We can also change it programmatically in spring boot.

@Component
public class ServerPortCustomizer implements     WebServerFactoryCustomizer<EmbeddedServletContainerCustomizer > {

@Override
public void customize(EmbeddedServletContainerCustomizer factory) {
    factory.setContextPath("/context-path");
    factory.setPort(8084);
}

}

We can also add an other way

@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {SpringApplication application =     new pringApplication(MyApplication.class);
    Map<String, Object> map = new HashMap<>();
    map.put("server.servlet.context-path", "/context-path");
    map.put("server.port", "808");
    application.setDefaultProperties(map);
    application.run(args);
    }       
}

using java command spring boot 1.X

java -jar my-app.jar --server.contextPath=/spring-boot-app     --server.port=8585 

using java command spring boot 2.X

java -jar my-app.jar --server.servlet.context-path=/spring-boot-app --server.port=8585 
Sequestrate answered 23/7, 2019 at 15:47 Comment(1)
we can also add the server port programaticallySequestrate
D
5

If you are using application.yml and spring version above 2.0 then configure in the below manner.

server:
  port: 8081
  servlet:
     context-path: /demo-api

Now all the API call will be like http://localhost:8081/demo-api/

Danieledaniell answered 6/11, 2019 at 12:18 Comment(0)
M
2

We can change context root path using a simple entry in the properties file.

application.properties

### Spring boot 1.x #########
server.contextPath=/ClientApp

### Spring boot 2.x #########
server.servlet.context-path=/ClientApp
Milled answered 3/1, 2020 at 12:31 Comment(0)
P
2

For below Spring boot 2 version you need to use below code

server:
   context-path: abc    

And For Spring boot 2+ version use below code

server:
  servlet:
    context-path: abc
Plectognath answered 21/8, 2020 at 12:25 Comment(0)
E
1

We can set it in the application.properties as API_CONTEXT_ROOT=/therootpath

And we access it in the Java class as mentioned below

@Value("${API_CONTEXT_ROOT}")
private String contextRoot;
Eveevection answered 9/12, 2016 at 10:47 Comment(0)
A
1

server.contextPath=/mainstay

works for me if i had one war file in JBOSS. Among multiple war files where each contain jboss-web.xml it didn't work. I had to put jboss-web.xml inside WEB-INF directory with content

<?xml version="1.0" encoding="UTF-8"?>
<jboss-web xmlns="http://www.jboss.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://www.jboss.com/xml/ns/javaee http://www.jboss.org/j2ee/schema/jboss-web_5_1.xsd">
    <context-root>mainstay</context-root>
</jboss-web>
Acyl answered 1/11, 2017 at 13:8 Comment(1)
It's not working with Wildfly23. Any idea?Guile
P
1

In Spring Boot 1.5:

Add the following property in application.properties:

server.context-path=/demo

Note: /demo is your context path URL.

Pedagogue answered 11/11, 2017 at 16:11 Comment(0)
B
1

We can set it using WebServerFactoryCustomizer. This can be added directly in the spring boot main method class which starts up the Spring ApplicationContext.

@Bean
    public WebServerFactoryCustomizer<ConfigurableServletWebServerFactory>
      webServerFactoryCustomizer() {
        return factory -> factory.setContextPath("/demo");
}
Broadside answered 23/1, 2020 at 3:2 Comment(0)
Y
1

If you use Spring Boot 2.x and want to pass the context path property in the command line, you should put double // like this:

--server.servlet.context-path=//your-path

That worked for me running in windows.

Yellowlegs answered 10/3, 2020 at 21:13 Comment(0)
M
1

It must be: server.servlet.context-path = / demo note that it does not have quotes only the value preceded by '/' this value goes in your application.properties file

Malikamalin answered 25/4, 2020 at 23:37 Comment(0)
P
1

You can use in Spring Boot: 2.1.6 like below:

server.servlet.context-path=/api-path
Psychosexual answered 26/7, 2020 at 15:53 Comment(0)
A
1

You can add this property to spring property file

spring.data.rest.basePath=/your_path
Adhesion answered 18/3, 2022 at 8:21 Comment(0)
A
1

The accepted answer works. With SpringBoot 3.0, this works:

server.servlet.context-path=/users
Aram answered 2/3, 2023 at 18:17 Comment(0)
D
0
<!-- Server port-->

server.port=8080

<!--Context Path of the Application-->

server.servlet.context-path=/ems
Derian answered 15/4, 2020 at 18:11 Comment(2)
Server port will be 8080. if you want any other port, you can replace 8080. Fro application context path i have set ems. You can set other path as per your requirementDerian
That's useful information, why don't you add it into your answer instead of a comment?Titus
S
0

I can see many outdated answers / context-path formats. Please use latest ones.

application.yml

server:
  servlet:
    context-path: /hello-context-path

application.properties

server.servlet.context-path=/hello-context-path
Survivor answered 7/4, 2023 at 20:39 Comment(0)
V
-1

context path can be directly integrated to the code but it is not advisable since it cannot be reused so write in the application.properties file server.contextPath=/name of the folder where you placed the code contextPath = name of the folder where you placed the code/ Note:watch the slash carefully.

Vulcan answered 10/11, 2017 at 13:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.