You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为Spring Integration HTTP端点生成OpenAPI/Swagger文档

Spring Integration HTTP端点生成标准OpenAPI文档实现方案(适配SpringBoot 2.2.6)

适用于Maven构建、基于spring-integration-http定义入站接口的场景,可同时输出标准OpenAPI格式yaml/json文档,提供Swagger GUI测试界面。

核心问题说明

spring-integration-http定义的入站端点(通过Http.inboundGateway/Http.inboundChannelAdapter创建)本质是注册到Spring MVC的请求处理器,但springfox、springdoc默认的扫描逻辑仅识别@RestController/@RequestMapping标注的控制器方法,无法自动扫描到IntegrationFlow中定义的接口,这是旧方案失效、生成无效文档的核心原因。
springfox目前已停止维护超过3年,对Spring Integration 5.x版本的元数据解析存在大量逻辑错误,生成的文档仅能复现curl调用、不符合OpenAPI规范,不建议继续使用。你给出的示例IntegrationFlow定义的/foo/{name}GET接口,可通过这套方案自动识别,不需要额外添加注解。

步骤1:引入版本匹配的依赖

SpringBoot 2.2.x对应springdoc-openapi版本选择1.6.15(1.7+版本要求SpringBoot 2.6+,2.x版本仅支持SpringBoot 3,会出现依赖冲突),在pom.xml中添加依赖:

<!-- OpenAPI核心 + Swagger UI -->
<dependency>
    <groupId>org.springdoc</groupId>
    <artifactId>springdoc-openapi-ui</artifactId>
    <version>1.6.15</version>
</dependency>
<!-- 对齐SpringBoot 2.2.6内置版本的Spring Integration HTTP依赖,项目已引入可忽略 -->
<dependency>
    <groupId>org.springframework.integration</groupId>
    <artifactId>spring-integration-http</artifactId>
    <version>5.2.5.RELEASE</version>
</dependency>

步骤2:自定义端点扫描逻辑,注册Integration HTTP端点到OpenAPI

通过springdoc提供的OpenApiCustomizer扩展点,直接从Spring容器中读取所有HTTP入站端点实例,解析路径、请求方法、参数、响应结构,手动构建符合OpenAPI规范的元数据,不需要在接口上额外加注解。
添加配置类:

import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.Operation;
import io.swagger.v3.oas.models.PathItem;
import io.swagger.v3.oas.models.media.StringSchema;
import io.swagger.v3.oas.models.parameters.PathParameter;
import org.springdoc.api.OpenApiCustomizer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.integration.http.inbound.HttpRequestHandlingEndpointSupport;
import org.springframework.integration.http.inbound.RequestMapping;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.RequestMethod;

import java.util.Arrays;
import java.util.Map;

@Configuration
public class SpringIntegrationOpenApiConfig {

    @Bean
    public OpenAPI customOpenAPI() {
        return new OpenAPI()
                .info(new io.swagger.v3.oas.models.info.Info()
                        .title("系统接口文档")
                        .version("1.0.0"));
    }

    @Bean
    public OpenApiCustomizer integrationEndpointCustomizer() {
        return openApi -> {
            Map<String, HttpRequestHandlingEndpointSupport> endpointBeans =
                    applicationContext.getBeansOfType(HttpRequestHandlingEndpointSupport.class);
            
            endpointBeans.forEach((beanName, endpoint) -> {
                RequestMapping requestMapping = endpoint.getRequestMapping();
                if (requestMapping == null || CollectionUtils.isEmpty(Arrays.asList(requestMapping.getPathPatterns()))) {
                    return;
                }
                Arrays.stream(requestMapping.getPathPatterns()).forEach(path -> {
                    PathItem pathItem = new PathItem();
                    for (RequestMethod method : requestMapping.getMethods()) {
                        Operation operation = buildBaseOperation(path, method);
                        switch (method) {
                            case GET: pathItem.setGet(operation); break;
                            case POST: pathItem.setPost(operation); break;
                            case PUT: pathItem.setPut(operation); break;
                            case DELETE: pathItem.setDelete(operation); break;
                            default: break;
                        }
                    }
                    openApi.getPaths().addPathItem(path, pathItem);
                });
            });
        };
    }

    private Operation buildBaseOperation(String path, RequestMethod method) {
        Operation operation = new Operation()
                .operationId(String.format("%s_%s", method.name(), path.replaceAll("[/{}\\s]", "_")))
                .summary(String.format("%s %s", method.name(), path));
        // 自动解析路径参数,比如示例中的{name}
        if (path.contains("{")) {
            Arrays.stream(path.split("/"))
                    .filter(seg -> seg.startsWith("{") && seg.endsWith("}"))
                    .map(seg -> seg.substring(1, seg.length() - 1))
                    .forEach(param -> operation.addParametersItem(
                            new PathParameter()
                                    .name(param)
                                    .required(true)
                                    .schema(new StringSchema())
                    ));
        }
        // 可在此扩展逻辑:根据端点关联的Transformer、payload类型自动映射请求体、响应体的Schema结构
        // 比如示例中test接口返回TestDTO序列化结果,可直接绑定对应DTO的Schema到响应字段
        return operation;
    }

    @Autowired
    private ApplicationContext applicationContext;
}

步骤3:添加配置开启yaml输出与Swagger UI

在application.yml中添加配置:

springdoc:
  swagger-ui:
    enabled: true
    path: /swagger-ui.html
  api-docs:
    enabled: true
    path: /v3/api-docs
  writer-with-default-pretty-printer: true

验证效果

启动项目后可直接访问对应地址:

  • Swagger GUI测试界面:/swagger-ui.html,所有Spring Integration HTTP端点会自动展示,支持直接发起接口调试
  • 标准OpenAPI yaml格式文档:/v3/api-docs.yaml,格式与Swagger Pet Store示例完全一致,可直接导入编辑器或用于生成多技术栈客户端代码
  • OpenAPI json格式文档:/v3/api-docs

扩展说明

  • 如果项目中存在统一的请求/响应封装,直接在buildBaseOperation方法中扩展逻辑即可,可通过反射读取端点绑定的转换器泛型、payload类型,自动映射请求响应Schema,不需要逐个接口维护
  • 如果需要过滤不需要展示的内部端点,在遍历endpointBeans时加自定义过滤规则即可

内容的提问来源于stack exchange,提问作者CoderJammer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 21:03:37