如何仅为休息控制器更改基本网址?

Posted

技术标签:

【中文标题】如何仅为休息控制器更改基本网址?【英文标题】:How to change base url only for rest controllers? 【发布时间】:2016-11-07 20:05:32 【问题描述】:

是否有任何配置选项允许仅更改其余控制器的基本 url,例如,如果我的 api 的基本 url 是 www.example.com/user/id 变为 www.example.com/rest/user/ id ?

我使用的是spring boot v1.3.2

我尝试通过添加 RequestMapping 创建扩展 RestController 的自定义注释。 这是示例,但它不起作用。

@Target(ElementType.TYPE) 
@Retention(RetentionPolicy.RUNTIME) 
@RestController 
@RequestMapping(value = "/rest", path = "/rest") 
public @interface MyRestController  

【问题讨论】:

可能重复:***.com/questions/32927937/… 【参考方案1】:

选项 1:自定义注释

创建一个自定义注释来声明基本 URL 并使用它来代替 @RestController。

CustomRestControllerAnnotation.java

package com.example.***.config;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@RestController
@RequestMapping("/rest")
public @interface CustomRestControllerAnnotation 

FirstRestController.java

package com.example.***.controller;

import org.springframework.web.bind.annotation.RequestMapping;

import com.example.***.config.CustomRestControllerAnnotation;

@CustomRestControllerAnnotation
public class FirstRestController 

    @RequestMapping("/first")
    public String firstMethod()
        return "First Controller";
    

SecondRestController.java

package com.example.***.controller;

import org.springframework.web.bind.annotation.RequestMapping;

import com.example.***.config.CustomRestControllerAnnotation;

@CustomRestControllerAnnotation
public class SecondRestController 

    @RequestMapping("/second")
    public String secondMethod()
        return "Second Controller";
    

选项 2:基本 RestController

通过创建一个用作所有实际控制器模板的基本控制器,您可以从一个位置有效地管理根 URL。

BaseRestController.java

package com.example.***.controller;

import org.springframework.web.bind.annotation.RequestMapping;

@RequestMapping("/rest")
public class BaseRestController 

然后,您只需为所有实际控制器扩展此类。

FirstRestController.java

package com.example.***.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class FirstRestController extends BaseRestController

    @RequestMapping("/first")
    public String firstMethod()
        return "First Controller";
    

SecondRestController.java

package com.example.***.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class SecondRestController extends BaseRestController

    @RequestMapping("/second")
    public String secondMethod()
        return "Second Controller";
    

选项 3:Spring Data REST

如果您的控制器从存储库提供数据,那么 Spring Data REST 可以消除大部分样板文件并解决您最初的问题。

pom.xml

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>

通过声明此依赖关系,您的所有存储库都会自动启用 REST。

您可以使用属性文件来控制基本 URL。

application.properties

spring.data.rest.basePath=/rest

【讨论】:

方法 1 和 2 不允许我在类上映射休息路径。所以方法3就像一个魅力。谢谢。【参考方案2】:

更新了 Spring Boot v2.1.0 的配置

在 Spring Boot v2.1.0 中,您可以在 application.properties 中配置基本 URL,例如

server.servlet.context-path = /baseApiName

Complete property configuration list

【讨论】:

spring boot 2.1.4.RELEASE、spring.mvc.servlet.path=/api 和 server.servlet.context-path=/api 都可以 问题仅与休息控制器有关。上下文路径适用于所有内容。 @Tom 请多解释一下,除了控制器之外,哪些组件会受到影响。据我了解,它将为每个restcontroller设置基本URL。 \@RestController 和\@Controller 之间存在差异。这个问题意味着所有 \@RestController 都需要一个基本 url,而不是 \@Controller。此外,例如上下文路径也将适用于 ws \@Endpoint 注释的肥皂端点。【参考方案3】:

通常您会定义一个 servlet 来处理您的所有(或特定的一组)restful 请求。然后,您将告诉该 servlet 侦听特定的 URL 模式,例如 /rest。控制器的 @RequestMapping 注释不知道该“***”模式。

例如,当引导您的 Spring Web 应用程序时,您可以手动创建该 restful servlet 并添加一个映射。整个设置有点太大,无法在此处发布,但请在下面找到一个 sn-p 以获得概念。

import org.springframework.web.servlet.DispatcherServlet;
import javax.servlet.ServletContext;
...

public class WebAppInitializer implements WebApplicationInitializer 

   public void onStartup(ServletContext servletContext) throws ServletException 
     ...
     ServletRegistration.Dynamic restfulServlet = servletContext.addServlet("myServlet", new DispatcherServlet(rootContext));
     restfulServlet.addMapping("/rest/*");
     ...

   

【讨论】:

【参考方案4】:

您应该在 application.properties 文件中添加server.servlet-path=/api,并且您应该发送所有请求,例如 domain/api/users/id

【讨论】:

以上是关于如何仅为休息控制器更改基本网址?的主要内容,如果未能解决你的问题,请参考以下文章

iOS 7. 仅为一个视图控制器更改页面方向

我如何在 grails 2.3.1 中使用控制器来休息 api?

Spring Boot 休息 API

Swift 4仅为一个视图控制器设置导航属性

如何仅为应用程序控制器启用日志记录调试级别?

如何发送长列表以与休息控制器一起使用