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?
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).
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
.yml .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
If you use Spring Boot 2.0.0 use:
server.servlet.context-path
server.servlet.contextPath=/api
servicename#api
, where #
is replaced by /
by tomcat.
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://stackoverflow.com/a/43856300/4449859
war
file using springboot v2.x
and tomcat v8.5
?
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.
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
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
If you're using spring-boot-starter-webflux use:
spring:
webflux:
base-path: /api
I swear to God... I forget this every single time.
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/
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;
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>
In Spring Boot 1.5:
Add the following property in application.properties
:
server.context-path=/demo
Note: /demo
is your context path URL.
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");
}
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.
You can use in Spring Boot: 2.1.6 like below:
server.servlet.context-path=/api-path
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
You can add this property to spring property file
spring.data.rest.basePath=/your_path
<!-- Server port-->
server.port=8080
<!--Context Path of the Application-->
server.servlet.context-path=/ems
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
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.
Success story sharing
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 theServerProperties
, the default configuredcontextPath
is""
(and it checks fornull
and not""
. The latter overrides your explicitly setcontextPath
.