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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28006501/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 05:26:46  来源:igfitidea点击:

How to specify prefix for all controllers in Spring Boot?

javaspringspring-boot

提问by Murali

I have controller mappings to /userand /order:

我有控制器映射到/user/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/usersand http://localhost:8080/api/orders, respectively.

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

How do I achieve this in Spring Boot?

我如何在 Spring Boot 中实现这一点?

采纳答案by Tomasz Janek

You can provide a mapping to root context path of your spring boot application to /api/*in your custom configuration.

您可以/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;
    }
}

or add this to your application.propertiesin src\main\resourcesfolder

或将此添加到您application.propertiessrc\main\resources文件夹中

server.contextPath=/api/*

EDIT

编辑

As of Spring Boot 2.x the property has been deprecatedand should be replaced with

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

server.servlet.contextPath=/api/*

More you find here Spring Boot Context Rootand here Add servlet mapping to DispatcherServlet

您可以在此处找到更多Spring Boot Context Root和此处将 servlet 映射添加到 DispatcherServlet

回答by deFreitas

If you want to add prefix just for some controllers I found two others solutions

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

Option 1 - Use spring SpEL to add a prefix variable for your controllers

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

Option 2 - Create a custom controller annotation

选项 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\"]";
    }
}

then test it

然后测试一下

curl -X GET localhost:8080/api/v1/users

回答by Eduardo

If you are using spring boot 2 (spring framework 5), there is a replacement of the property in your application.properties:

如果您使用的是 spring boot 2(spring 框架 5),则会替换您的application.properties:

server.contextPath

for:

为了:

server.servlet.context-path=

回答by geeves

For those interested, here is a Kotlin take on deFreitas' Option 2 Componentas I was unable to use spring.data.rest.basePathor server.servlet.contextPathin application.yaml. (This is with Spring Boot 2.1.2 and Kotlin 1.13.11)

对于那些有兴趣,这里是一个科特林拿上deFreitas'选项2分量,因为我无法使用spring.data.rest.basePathserver.servlet.contextPathapplication.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 = ""
)

If you're using IntelliJ, optimizing imports will probably remove the Kotlin annotation imports for brevity.

如果您使用 IntelliJ,为了简洁起见,优化导入可能会删除 Kotlin 注释导入。

回答by Bishal Jaiswal

Add your default path in the application.propertiesas:

application.propertiesas 中添加您的默认路径:

server.servlet.contextPath=/mainPath

Here /mainPathwill be the prefix for all the controller

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

回答by Gary Tessman

server.servlet.context-pathis 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:

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>

回答by troy

Additional. If you use .yaml, you could write it as:

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

server:
  servlet:
    context-path: /api