如何在Spring Boot中为所有控制器指定前缀?


72

我有控制器映射/user/order

@RestController
@RequestMapping("/users")
public class UserController {
    ...
}

@RestController
@RequestMapping("/orders")
public class OrderController {
    ...
}

我想分别通过URLhttp://localhost:8080/api/users 和访问这些URL http://localhost:8080/api/orders

如何在Spring Boot中实现这一目标?


Answers:


64

您可以/api/*在自定义配置中提供到Spring Boot应用程序的根上下文路径的映射。

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.propertiesinsrc\main\resources文件夹中

server.contextPath=/api/*

编辑

从Spring Boot 2.x开始,该属性已被弃用,应替换为

server.servlet.contextPath=/api/*

您可以在此处找到更多的内容Spring Boot Context Root,并在此处将servlet映射添加到DispatcherServlet


64
这为所有内容(不仅是控制器)添加了前缀
CESCO 2015年

17
它应该只是“ server.contextPath = / api /”。在Spring Boot版本1.3.5中带有尾随*会引起错误
Anand

1
请注意,在1.4中已弃用org.springframework.boot.context.embedded.ServletRegistrationBean,并引入了其替代品org.springframework.boot.web.servlet.ServletRegistrationBean。弃用的类在1.5中被删除
二进制文件,

6
文件中的server.servlet.context-path = /api/*坐席application.properties给了我Error registering Tomcat:type=TomcatEmbeddedWebappClassLoader,host=localhost,context=/api/* - ContextPath must start with '/' and not end with '/'错误。server.servlet.context-path = /api不带引号的属性是启动应用程序所需的属性。
斯蒂芬

4
对于Spring Boot 2.0,它必须像server.servlet.context-path=/api
HalilİbrahimOymacı19年

41

如果您只想为某些控制器添加前缀,我发现了另外两个解决方案

选项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

4
是的,但是如果您的UserController中有很多方法该怎么办?现在,您已经在类级别权衡了编写@RequestMapping(“ / api / users”)的过程,以在每个方法的RequestMapping前面加上“ users”作为前缀。
吉尔伯特·阿里纳斯·匕首,

1
为什么将@Component用作批注和别名而不是@RestController是有原因的?
JimBob

@JimBob没有,你可以UE@RestController以及
deFreitas

16

如果您使用的是Spring Boot 2(Spring框架5),那么您的中的属性将被替换application.properties

server.contextPath

对于:

server.servlet.context-path=

谢谢。我想添加'/ api'前缀并由server.servlet.context-path = / api添加
Kishan Solanki

10

application.propertiesas中添加默认路径:

server.servlet.contextPath=/mainPath

/mainPath将是所有控制器的前缀


在当前版本的Spring Boot中,该属性名称为context-path。
Sinux

4

除了有关更改上下文路径的应用程序属性的其他注释之外,在Spring Boot 2.3.1中,还可以使用应用程序属性单独设置调度程序servlet的前缀。

spring.mvc.servlet.path=/api

请求映射不会在您的控制器中更改。尽管上下文路径将整个应用程序移至其他路径,但是servlet路径仅限制了由调度程序servlet处理的URL。servlet路径与web.xml中的servlet映射等效。可以从任何其他URL访问不使用调度程序servlet的其他资源。

如果您还有其他未映射到该/api前缀的控制器,则除非您为这些控制器声明了另一个具有不同前缀的调度程序servlet,否则它将无法工作。


3

对于那些感兴趣的人,这里是Kotlin对deFreitas的Option 2 Component的认可,因为我无法使用spring.data.rest.basePathserver.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注释导入。


0

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>

0

额外。如果使用.yaml,则可以将其编写为:

server:
  servlet:
    context-path: /api

0

在application.yml中添加以下内容:

server:
  servlet:
    context-path: "/contextPath"
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.