Как указать префикс для всех контроллеров в Spring Boot?
У меня есть сопоставления контроллеров с /user
и /order
:
@RestController
@RequestMapping("/users")
public class UserController {
...
}
@RestController
@RequestMapping("/orders")
public class OrderController {
...
}
Я хочу получить доступ к ним по URL-адресу в http://localhost:8080/api/users
и http://localhost:8080/api/orders
, соответственно.
Как достичь этого в Spring Boot?
Ответы
Ответ 1
Вы можете указать сопоставление корневого контекстного пути вашего приложения загрузки spring с /api/*
в вашей настраиваемой конфигурации.
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;
}
}
или добавьте его в папку application.properties
в src\main\resources
server.contextPath=/api/*
Подробнее здесь Spring Загрузочный контекстный корень и здесь Добавить отображение сервлета в DispatcherServlet
Ответ 2
Если вы хотите добавить префикс только для некоторых контроллеров, я нашел два других решения
Вариант 1. Использование Spring SpEL для добавления префиксной переменной для ваших контроллеров.
@RestController
@RequestMapping(path = "${v1API}/users")
public class V1FruitsController {
@GetMapping(path = "")
@ResponseBody
public String list(){
return "[\"Joe\", \"Peter\"]";
}
}
application.properties
v1API=/api/v1
Вариант 2. Создание пользовательской аннотации контроллера
@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\"]";
}
}
тогда проверь
curl -X GET localhost:8080/api/v1/users
Ответ 3
Если вы используете весеннюю загрузку 2 (spring framework 5), в вашем application.properties
есть замена свойства application.properties
:
server.contextPath
за:
server.servlet.context-path=
Ответ 4
Для тех, кто интересуется, вот Kotlin берет компонент Option 2 deFreitas, поскольку я не смог использовать spring.data.rest.basePath
или server.servlet.contextPath
в application.yaml
. (Это с Spring Boot 2.1.2 и 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 = ""
)
Если вы используете IntelliJ, оптимизация импорта, скорее всего, удалит импорт аннотаций Kotlin для краткости.
Ответ 5
Добавьте путь по умолчанию в application.properties
как:
server.servlet.contextPath=/mainPath
Здесь /mainPath
будет префикс для всего контроллера
Ответ 6
server.servlet.context-path
- правильный путь. Не server.servlet.contextPath
, и, к сожалению, он не поддерживает списки, которые вы могли бы сделать в web.xml следующим образом:
<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>