文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

基于Spring Boot给所有Controller接口添加统一前缀的五种方式

2024-11-29 18:53

关注

1. 简介

在Spring Boot应用程序中,每个控制器都可以有自己的URL映射。这使得单个应用程序能够在多个位置提供Web接口。例如,我们可以将API接口分组为逻辑分组,如内部和外部。

然而,有时我们可能希望将所有接口置于一个共同的前缀之下。在本篇文章中,我将深入探讨为所有Spring Boot Controller使用共同前缀的不同方法。

2. 基于Servlet上下文

在Spring应用程序中,负责处理Web请求的主要组件是DispatcherServlet。通过自定义这个组件,我们可以相当程度地控制请求的路由方式。

接下来先来看看两种自定义DispatcherServlet的方法,这样我们的所有应用程序端点都将可以在一个共同的URL前缀下访问。

2.1 配置DispatcherServlet Bean

@Configuration
public class DispatcherServletCustomConfiguration {


  @Bean
  public DispatcherServlet dispatcherServlet() {
    return new DispatcherServlet() ;
  }
  @Bean
  public ServletRegistrationBean dispatcherServletRegistration() {
    ServletRegistrationBean registration = new ServletRegistrationBean(
      dispatcherServlet(), "/api/") ;
    registration.setName("dispatcherServlet") ;
    return registration ;
  }
}

在这里,我们创建了一个封装 DispatcherServlet Bean 的 ServletRegistrationBean。 设置了该Servlet的访问前缀路径为:/api/。这意味着我们的所有接口都必须通过该基础 URL 前缀进行访问。

2.2 基于配置属性

我们也可以通过使用应用程序属性来达到同样的效果。在 Spring Boot 2.x 之后的版本中,我们可以在 application.yml文件中添加以下内容:

server:
  servlet:
    contextPath: /api

但在之前的版本则需要通过如下方式配置

server:
  contextPath: /api

在2.1中我们通过编程的方式设置了统一的前缀,其实我们还可以通过如下属性配置

spring:
  mvc:
    servlet:
      path: /api

这种方式通过是给DispatcherServlet配置路径访问前缀。

基于Servlet上下文方式的优缺点:

上面介绍的两种方法的主要优点也是它们的主要缺点:它们会影响应用程序中的每个接口。对于一些应用程序来说,这可能完全没问题。然而,一些应用程序可能需要使用标准的端点映射来与第三方服务进行交互——例如OAuth交换。在这些情况下,这样的全局解决方案可能并不合适。

3. 基于注解

为 Spring 应用程序中的所有控制器添加前缀的另一种方法是使用注解。下面,我将介绍两种不同的方法。

3.1 使用SpEL

使用 Spring Expression Language (SpEL) 和标准 @RequestMapping 注解。使用这种方法,我们只需在每个控制器中添加一个需要前缀的属性,如下示例:

@Controller
@RequestMapping(path = "${pack.app.apiPrefix}/users")
public class UserController {
}

配置文件中我们只需要配置上pack.app.apiPrefix属性即可。

3.2 自定义注解

这种方式需要我们自定义注解,这完全可以仿照@GetMapping、@PostMapping等这类注解来实现即可,如下示例:

@RequestMapping(value = "/api/")
public @interface PackMapping {
}
// 使用
@RestController
@PackMapping
public class SomeController {
  @RequestMapping("/users")
  public String getAll(){
    return "..." ;
  }
}

基于注解的优缺点:

这两种方法解决了前一种方法的主要问题:它们都能对哪些控制器获得前缀进行细粒度控制。我们可以只对特定控制器应用注解,而不是影响应用程序中的所有接口。

4. 服务端转发

使用服务器端转发。与重定向不同,转发不涉及向客户端发送响应。这意味着我们的应用程序可以在接口之间传递请求,而不会影响客户端。

下面编写一个简单的控制器,其中包含两个接口:

@RestController
public class EndpointController {
  @GetMapping("/endpoint1")
  public String endpoint1() {
      return "Hello from endpoint 1";
  }
  @GetMapping("/endpoint2")
  public String endpoint2() {
      return "Hello from endpoint 2";
  }
}

接下来,我们根据所需的前缀创建一个新控制器:

@Controller
@RequestMapping("/api/endpoint")
public class ApiPrefixController {
  @GetMapping
  public ModelAndView route(ModelMap model, HttpServletRequest request) {
    String action = request.getHeader("X-ACTION");
    return switch (action) {
      case null -> new ModelAndView("forward:/error") ;
      case "xxx" -> new ModelAndView("forward:/endpoint1", model) ;
      case "zzz" -> new ModelAndView("forward:/endpoint2", model) ;
      default -> new ModelAndView("forward:/home") ;
    } ;
  }
}

这个控制器有一个接口,它充当路由器。将原始请求转发到我们的另外两个端点之一。

5. Nginx反向代理

通过Nginx配置反向代理来管理统一的前缀

server {
  listen              80;
  server_name         default;


  location /api/ {
    proxy_set_header Host $host ;
    proxy_set_header  X-Real-IP        $remote_addr ;
    proxy_set_header  X-Forwarded-For  $proxy_add_x_forwarded_for ;
    proxy_set_header X-NginX-Proxy true ;


    rewrite ^/api/(.*)$ /$1 break ;
    proxy_pass http://www.pack.com ;
  }
}

这种方式最为简单,不对我们的业务代码做任何的调整。

来源:Spring全家桶实战案例源码内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯