springboot返回所有接口详细信息

springboot返回所有接口详细信息

简单来说

就是我们通过访问一个接口能看到我们所有的API接口的数量。

以及路径和请求方法。

这个是我今天再做一个项目的首页的时候。

前端的设计是有一个这样的需求

因此这个数据需要我们从后台来进行一个动态的获取。

这里我们所需要用到的就是

spring-boot-starter-actuator

首先导入依赖

xml 复制代码
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
java 复制代码
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

import org.springframework.context.ApplicationContext;

import java.util.*;

@RestController
@RequestMapping("/uapi/api-list")
@Tag(name = "API列表", description = "API列表")
public class ApiListController {

    private final RequestMappingHandlerMapping handlerMapping;

    @Autowired
    public ApiListController(ApplicationContext context) {
        this.handlerMapping = context.getBean("requestMappingHandlerMapping", RequestMappingHandlerMapping.class);
    }

    @GetMapping
    @Operation(summary = "获取所有API列表")
    public Map<String, Object> listAllApi() {
        Map<RequestMappingInfo, HandlerMethod> handlerMethods = handlerMapping.getHandlerMethods();
        List<Map<String, String>> apiList = new ArrayList<>();

        for (Map.Entry<RequestMappingInfo, HandlerMethod> entry : handlerMethods.entrySet()) {
            RequestMappingInfo info = entry.getKey();
            Set<String> paths = new HashSet<>();

            // ✅ 只使用 Spring Boot 3 推荐方式
            if (info.getPathPatternsCondition() != null) {
                info.getPathPatternsCondition().getPatterns()
                    .forEach(p -> paths.add(p.getPatternString()));
            }

            Set<RequestMethod> methods = info.getMethodsCondition().getMethods();

            for (String path : paths) {
                if (methods.isEmpty()) {
                    apiList.add(Map.of("method", "ANY", "path", path));
                } else {
                    for (RequestMethod method : methods) {
                        apiList.add(Map.of("method", method.name(), "path", path));
                    }
                }
            }
        }

        Map<String, Object> result = new HashMap<>();
        result.put("count", apiList.size());
        result.put("apis", apiList);
        return result;
    }
}

上面贴出的是springboot3的写法。

这个代码的核心原理就是

通过反射获取 Spring Boot 项目中所有控制器方法的路径和请求方式,然后把这些信息组织成一个列表,返回给用户。通过这种方式,开发者可以查看当前 Spring Boot 项目中的所有公开 API 接口及其支持的请求方法。

这一过程的核心依赖是 Spring Boot 的 RequestMappingHandlerMapping 类,该类负责管理所有请求路径的映射,能够获取每个路径的具体信息。

java 复制代码
Map<RequestMappingInfo, HandlerMethod> handlerMethods = handlerMapping.getHandlerMethods();
  • handlerMapping.getHandlerMethods() 通过 Spring 的 RequestMappingHandlerMapping 类获取所有已经注册的请求映射信息。
  • 这里返回的是一个 MapkeyRequestMappingInfo(包含了路径和请求方法的相关信息),valueHandlerMethod(指向处理该请求的控制器方法)。

后面的就是在对返回的数据进行一个处理。

之后就会返回一个这样的json

这样就完成了我们的需求。

需要注意的是这段代码

java 复制代码
if (info.getPathPatternsCondition() != null) {
    info.getPathPatternsCondition().getPatterns()
        .forEach(p -> paths.add(p.getPatternString()));
}

✅ Spring Boot 3.x 的新方式:使用 getPathPatternsCondition() 获取路径集合(Pattern 类型),然后转成字符串加到 paths 里。

Spring Boot 2.x 是用 getPatternsCondition(),在 3.x 中已经废弃。

后面我贴了一个兼容版本,既可以兼容springboot3也可以兼容springboot2

java 复制代码
@GetMapping("/api-list")
public Map<String, Object> listAllApi() {
    Map<RequestMappingInfo, HandlerMethod> handlerMethods = handlerMapping.getHandlerMethods();
    List<Map<String, String>> apiList = new ArrayList<>();

    for (Map.Entry<RequestMappingInfo, HandlerMethod> entry : handlerMethods.entrySet()) {
        RequestMappingInfo info = entry.getKey();
        Set<String> paths = new HashSet<>();

        // Spring Boot 2.x
        if (info.getPatternsCondition() != null) {
            paths.addAll(info.getPatternsCondition().getPatterns());
        }

        // Spring Boot 3.x
        if (info.getPathPatternsCondition() != null) {
            info.getPathPatternsCondition().getPatterns()
                .forEach(p -> paths.add(p.getPatternString()));
        }

        Set<RequestMethod> methods = info.getMethodsCondition().getMethods();

        for (String path : paths) {
            if (methods.isEmpty()) {
                apiList.add(Map.of("method", "ANY", "path", path));
            } else {
                for (RequestMethod method : methods) {
                    apiList.add(Map.of("method", method.name(), "path", path));
                }
            }
        }
    }

    Map<String, Object> result = new HashMap<>();
    result.put("count", apiList.size());
    result.put("apis", apiList);
    return result;
}
相关推荐
南囝coding26 分钟前
Claude 封禁中国?为啥我觉得是个好消息
前端·后端
六边形工程师33 分钟前
Docker安装神通数据库ShenTong
后端
六边形工程师35 分钟前
快速入门神通数据库
后端
重生成为编程大王40 分钟前
FreeMarker快速入门指南
java·后端
Dear.爬虫1 小时前
Golang的协程调度器原理
开发语言·后端·golang
元闰子1 小时前
怎么用CXL加速数据库?· SIGMOD'25
数据库·后端·面试
幂简集成1 小时前
GraphQL API 性能优化实战:在线编程作业平台指南
后端·性能优化·graphql
编码浪子1 小时前
趣味学RUST基础篇(构建命令行程序1)
开发语言·后端·rust
周小码1 小时前
极快文本嵌入推理:Rust构建高性能嵌入推理解决方案
开发语言·后端·rust
蜗牛快跑1232 小时前
拆巨资让 Claude Code 和 Codex 同时住进了我的终端里
前端·后端·ai编程