Подтвердить что ты не робот

Как указать префикс для всех контроллеров в 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?

4b9b3361

Ответ 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>