Reputation: 3542
I have controller mappings to /user
and /order
:
@RestController
@RequestMapping("/users")
public class UserController {
...
}
@RestController
@RequestMapping("/orders")
public class OrderController {
...
}
I want to access these by URL at http://localhost:8080/api/users
and http://localhost:8080/api/orders
, respectively.
How do I achieve this in Spring Boot?
Upvotes: 110
Views: 129380
Reputation: 1183
You can provide a mapping to root context path of your spring boot application to /api/*
in your custom configuration.
import org.springframework.boot.autoconfigure.web.DispatcherServletAutoConfiguration;
import org.springframework.boot.context.embedded.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.DispatcherServlet;
@Configuration
public class DispatcherServletCustomConfiguration {
@Bean
public DispatcherServlet dispatcherServlet() {
return new DispatcherServlet();
}
@Bean
public ServletRegistrationBean dispatcherServletRegistration() {
ServletRegistrationBean registration = new ServletRegistrationBean(
dispatcherServlet(), "/api/");
registration.setName(DispatcherServletAutoConfiguration.DEFAULT_DISPATCHER_SERVLET_REGISTRATION_BEAN_NAME);
return registration;
}
}
or add this to your application.properties
in src\main\resources
folder
server.servlet.contextPath=/api
EDIT
Before Spring Boot 2.x, the proper to be used was server.contextPath
, but as of Spring Boot 2.x it has been deprecated and replaced with server.servlet.contextPath
.
More you find here Spring Boot Context Root and here Add servlet mapping to DispatcherServlet
Upvotes: 85
Reputation: 141
Since spring-webmvc-5.1.x
import org.springframework.context.annotation.Configuration;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.method.HandlerTypePredicate;
import org.springframework.web.servlet.config.annotation.PathMatchConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebConfiguration implements WebMvcConfigurer {
@Override
public void configurePathMatch(PathMatchConfigurer configurer) {
configurer.addPathPrefix("/api",
HandlerTypePredicate.forAnnotation(RestController.class));
}
}
Upvotes: 10
Reputation: 139
Add this at application.properties
server.servlet.context-path=/api/v1/
Upvotes: 2
Reputation: 627
In application.yml add this:
server:
servlet:
context-path: "/contextPath"
Upvotes: 4
Reputation: 1306
In addition to the other comments about changing the application property for the context path, you can also use an application property to set the prefix for the dispatcher servlet alone, in Spring Boot 2.3.1.
spring.mvc.servlet.path=/api
The request mappings would not change in your controllers. While context path moves the entire application to a different path, servlet path only limits the URLs that are handled by the dispatcher servlet. The servlet path is the equivalent of the servlet mapping in web.xml. Other resources that do not use the dispatcher servlet can be accessed from any other URL.
If you have other controllers that are not mapped to the /api
prefix, then this will not work, unless you declare a second dispatcher servlet with a different prefix for those controllers.
Upvotes: 12
Reputation: 2515
Additional. If you use .yaml
, you could write it as:
server:
servlet:
context-path: /api
Upvotes: 0
Reputation: 1863
Add your default path in the application.properties
as:
server.servlet.contextPath=/mainPath
Here /mainPath
will be the prefix for all the controller
Upvotes: 14
Reputation: 543
server.servlet.context-path
is the correct path. Not server.servlet.contextPath
, and unfortunately it doesn't seem to support lists which you could do in web.xml like this:
<servlet>
<description>Servlet used by Spring MVC to handle all requests into the application</description>
<servlet-name>spring</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>/app1/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>/app2/*</url-pattern>
</servlet-mapping>
Upvotes: 1
Reputation: 4448
If you want to add prefix just for some controllers I found two others solutions
@RestController
@RequestMapping(path = "${v1API}/users")
public class V1FruitsController {
@GetMapping(path = "")
@ResponseBody
public String list(){
return "[\"Joe\", \"Peter\"]";
}
}
application.properties
v1API=/api/v1
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
@RequestMapping("/api/v1")
public @interface V1APIController {
@AliasFor(annotation = Component.class)
String value() default "";
}
@V1APIController
public class UserController {
@RequestMapping("/users")
@ReponseBody
public String index(){
return "[\"Joe\", \"Peter\"]";
}
}
then test it
curl -X GET localhost:8080/api/v1/users
Upvotes: 66
Reputation: 116
For those interested, here is a Kotlin take on deFreitas' Option 2 Component as I was unable to use spring.data.rest.basePath
or server.servlet.contextPath
in application.yaml
. (This is with Spring Boot 2.1.2 and Kotlin 1.13.11)
package com.myproject.controller
import org.springframework.core.annotation.AliasFor
import org.springframework.stereotype.Component
import org.springframework.web.bind.annotation.RequestMapping
import kotlin.annotation.MustBeDocumented
import kotlin.annotation.Retention
import kotlin.annotation.Target
import kotlin.annotation.AnnotationRetention
@Target(AnnotationTarget.CLASS, AnnotationTarget.FILE)
@Retention(AnnotationRetention.RUNTIME)
@MustBeDocumented
@Component
@RequestMapping("/api/v1")
annotation class V1ApiController(
@get:AliasFor(annotation = Component::class)
val value: String = ""
)
If you're using IntelliJ, optimizing imports will probably remove the Kotlin annotation imports for brevity.
Upvotes: 3
Reputation: 2280
If you are using spring boot 2 (spring framework 5), there is a replacement of the property in your application.properties
:
server.contextPath
for:
server.servlet.context-path=
Upvotes: 22