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

时间:2015-01-18 02:14:59

标签: java spring spring-boot

我有/user/order的控制器映射:

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

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

我想分别通过http://localhost:8080/api/usershttp://localhost:8080/api/orders的网址访问这些内容。

如何在Spring Boot中实现此目的?

9 个答案:

答案 0 :(得分:43)

您可以在自定义配置中将弹簧启动应用程序的根上下文路径映射到/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 Boot Context RootAdd servlet mapping to DispatcherServlet

找到更多内容

答案 1 :(得分:13)

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

选项1-使用spring SpEL为您的控制器添加前缀变量

// Set the timeout to a variable to reference later
var pageReloader = setTimeout(function(){
      window.location.reload(1);
    }, 10000),
   // This function checks if the value in the input is different to the one at page load. If it has changed, stop the refresh
    checkInputDirty = function(event){
      if (event.target.value != event.target.defaultValue) {
        clearTimeout(pageReloader);
      }
    },
    userInput = document.querySelector('input[type=text]');

//Add listeners to keyup and change events.
userInput.addEventListener('keyup', checkInputDirty);
userInput.addEventListener('change', checkInputDirty);

application.properties

var pageReloader = setTimeout(function(){
      window.location.reload(1);
    });

$('input[type=text]').on('keyup change', function(input){
  if (this.val() != this[0].defaultValue) { //jQuery doesn't expose default value directly, so get it from the DOM node
    clearTimeout(pageReloader);
  }
});

选项2-创建自定义控制器注释

@RestController
@RequestMapping(path = "${v1API}/users")
public class V1FruitsController {

    @GetMapping(path = "")
    @ResponseBody
    public String list(){
        return "[\"Joe\", \"Peter\"]";
    }
}

然后测试

v1API=/api/v1

答案 2 :(得分:4)

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

spring.mvc.servlet.path=/api

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

如果您还有其他未映射到/api前缀的控制器,则除非您为第二个调度程序servlet声明了不同的前缀,否则这将不起作用。

答案 3 :(得分:3)

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

server.contextPath

针对:

server.servlet.context-path=

答案 4 :(得分:1)

application.properties中将默认路径添加为:

server.servlet.contextPath=/mainPath

mainPath将是所有控制器的前缀

答案 5 :(得分:0)

对于那些感兴趣的人,这里是Kotlin对deFreitas' Option 2 Component的看法,因为我无法在spring.data.rest.basePath中使用server.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 = ""
)

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

答案 6 :(得分: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>

答案 7 :(得分:0)

其他。如果您使用.yaml,则可以将其写为:

server:
  servlet:
    context-path: /api

答案 8 :(得分:0)

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

server:
  servlet:
    context-path: "/contextPath"