Skip to content

🌐 Spring Integration HTTP 命名空间支持详解

本教程将使用 Kotlin + Spring Boot 注解方式全面解析 HTTP 集成功能,替代传统 XML 配置方案


🚀 1. 快速入门:配置基础

kotlin

@Configuration
@EnableIntegration
class HttpIntegrationConfig {

    @Bean
    fun httpMessageHandler(): HttpRequestHandlingMessagingGateway {
        return Http.inboundGateway("/api")
            .requestChannel(MessageChannels.direct("httpInput").get())
            .replyChannel(MessageChannels.direct("httpOutput").get())
            .mappedRequestHeaders("Content-Type")
            .get()
    }
}

关键配置说明

  • Http.inboundGateway():替代 XML 的 <inbound-gateway>
  • requestChannel/replyChannel:定义请求/响应通道
  • mappedRequestHeaders:指定透传的请求头

📥 2. 入站处理方案对比

kotlin
@Bean
fun inboundAdapter(): HttpRequestHandlingEndpointSupport {
    return Http.inboundChannelAdapter("/data")
        .requestChannel(MessageChannels.direct("dataChannel").get())
        .supportedMethods(HttpMethod.POST, HttpMethod.PUT)
        .get()
}
kotlin
@Bean
fun inboundGateway(): HttpRequestHandlingMessagingGateway {
    return Http.inboundGateway("/process")
        .requestChannel(MessageChannels.direct("processChannel").get())
        .replyChannel(MessageChannels.direct("resultChannel").get())
        .get()
}

⚠️ 选择原则

  • 使用通道适配器处理日志记录等无需响应的场景
  • 使用网关处理需要返回结果的 API 请求

🗺️ 3. 请求映射高级配置

kotlin
@Bean
fun advancedGateway(): HttpRequestHandlingMessagingGateway {
    return Http.inboundGateway("/user/{userId}")
        .requestChannel(MessageChannels.direct("userChannel").get())
        .payloadExpression("#pathVariables.userId") 
        .header("userAgent", "headers['User-Agent']") 
        .crossOrigin(CrossOrigin("*").allowedHeaders("*"))
        .requestMapping { m: RequestMapping ->
            m.consumes(MediaType.APPLICATION_JSON_VALUE)
             .produces(MediaType.APPLICATION_JSON_VALUE)
        }
        .get()
}

🔍 表达式变量说明

  • #pathVariables:路径参数映射
  • #requestParams:查询参数
  • #requestHeaders:请求头信息
  • #cookies:Cookie 数据

🌍 4. CORS 跨域配置

kotlin
@Bean
fun corsEnabledGateway(): HttpRequestHandlingMessagingGateway {
    return Http.inboundGateway("/public/api")
        .requestChannel(MessageChannels.direct("publicChannel").get())
        .crossOrigin(CrossOrigin("https://trusted-domain.com") 
            .allowedHeaders("Authorization", "Content-Type")
            .exposedHeaders("X-Custom-Header")
            .allowCredentials(true)
            .maxAge(3600))
        .get()
}

最佳实践

  • 生产环境避免使用 allowedHeaders("*")
  • 敏感接口设置 allowCredentials(false)

⚙️ 5. 响应状态码控制

kotlin
@Bean
fun statusCodeGateway(): HttpRequestHandlingMessagingGateway {
    return Http.inboundGateway("/order")
        .requestChannel(MessageChannels.direct("orderChannel").get())
        .statusCodeFunction { message ->
            when (message.headers["orderStatus"]) {
                "PROCESSING" -> HttpStatus.ACCEPTED
                else -> HttpStatus.OK
            }
        }
        .errorChannel(MessageChannels.direct("errorChannel").get())
        .get()
}
kotlin
@ServiceActivator(inputChannel = "errorChannel")
fun handleErrors(message: Message<Exception>) {
    val response = when (val ex = message.payload) {
        is TimeoutException -> "Timeout" to HttpStatus.GATEWAY_TIMEOUT
        else -> "Server Error" to HttpStatus.INTERNAL_SERVER_ERROR
    }
    // 自定义错误处理逻辑
}

🔗 6. 出站网关配置

kotlin
@Bean
fun outboundGateway(): HttpRequestExecutingMessageHandler {
    return Http.outboundGateway("https://api.external.com/data")
        .httpMethod(HttpMethod.GET)
        .expectedResponseType(String::class.java)
        .uriVariable("param", "payload") 
        .get()
}

🔄 URI 变量动态映射

kotlin
@Bean
fun dynamicOutboundGateway(): HttpRequestExecutingMessageHandler {
    return Http.outboundGateway("https://api.service.com/{resource}/{id}")
        .httpMethodExpression("headers['method']")
        .uriVariable("resource", "headers['resourceType']")
        .uriVariable("id", "payload.id") 
        .get()
}

⚠️ 常见问题解决

**编码问题**

当调用特殊 API(如 RabbitMQ 管理接口)时需禁用自动编码:

kotlin
Http.outboundGateway("http://localhost:15672/api/queues/%2F/{name}")
    .encodingMode(EncodingMode.NONE) 
    .get()

**超时处理**

默认超时(30 秒)可能导致阻塞:

kotlin
Http.outboundGateway("https://slow.api.com")
    .replyTimeout(Duration.ofMinutes(2)) 
    .get()

**安全建议**

生产环境必须启用 HTTPS:

kotlin
@Bean
fun secureRequestFactory(): ClientHttpRequestFactory {
    val factory = Netty4ClientHttpRequestFactory()
    factory.sslContext = SslContextBuilder.forClient().build()
    return factory
}

现代配置 vs 传统 XML

特性Kotlin DSLXML 配置
路由定义类型安全的方法链<http:outbound-gateway> 标签
表达式支持原生 Kotlin 表达式SpEL 表达式
依赖管理自动注入 Bean手动声明 Bean 引用
可读性⭐⭐⭐⭐⭐⭐⭐

迁移建议

将旧 XML 配置逐步替换为:

kotlin
// 1. 创建 @Configuration 类
// 2. 使用 Http 命名空间的方法
// 3. 通过 @Bean 声明组件

通过本教程,您已掌握使用 Kotlin DSL 配置 Spring Integration HTTP 组件的核心技巧。实际开发中优先选择注解配置方案,可获得更好的类型安全和代码可维护性。