Skip to content

Spring Integration HTTP 支持教程

概述

Spring Integration 的 HTTP 支持允许开发者轻松处理 HTTP 请求和响应。本教程将介绍如何使用 Kotlin 和注解配置方式实现 HTTP 网关,适合 Spring 初学者快速掌握核心功能。

TIP

HTTP 支持的核心组件:

  • HttpInboundEndpoint:处理入站 HTTP 请求
  • HttpRequestExecutingMessageHandler:执行出站 HTTP 请求

环境准备

添加依赖

build.gradle.kts 中添加以下依赖:

kotlin
dependencies {
    implementation("org.springframework.integration:spring-integration-http:6.5.1")
    compileOnly("jakarta.servlet:jakarta.servlet-api:6.0.0") 
}
kotlin
<!-- Maven 用户使用此配置 -->
<dependency>
    <groupId>org.springframework.integration</groupId>
    <artifactId>spring-integration-http</artifactId>
    <version>6.5.1</version>
</dependency>

IMPORTANT

jakarta.servlet-api 依赖必须由 Servlet 容器(如 Tomcat)提供,确保使用 compileOnly 作用域

HTTP 入站网关配置

基础配置

创建处理 GET 请求的入站网关:

kotlin
@Configuration
@EnableIntegration
class HttpInboundConfig {

    @Bean
    fun httpInboundChannelAdapter(): HttpRequestHandlingMessagingGateway {
        return HttpRequestHandlingMessagingGateway(true).apply {
            setRequestMapping(
                RequestMapping().apply {
                    methods = arrayOf(HttpMethod.GET)
                    pathPatterns = arrayOf("/api/data")
                }
            )
            setRequestChannelName("httpRequestChannel")
            setReplyChannelName("httpReplyChannel")
        }
    }
    
    @Bean
    fun httpRequestChannel() = DirectChannel()
    
    @Bean
    fun httpReplyChannel() = DirectChannel()
}

请求处理流程

kotlin
@Bean
fun integrationFlow() = IntegrationFlow.from("httpRequestChannel")
    .enrichHeaders { it.header("TIMESTAMP", System.currentTimeMillis()) }
    .transform(Transformers.toJson())
    .handle(LoggingHandler(LoggingHandler.Level.INFO))
    .channel("httpReplyChannel")
    .get()

NOTE

入站网关将自动处理:

  • HTTP 请求到消息的转换
  • 响应状态码设置
  • 异常处理

HTTP 出站网关配置

发送 GET 请求

kotlin
@Bean
fun httpOutboundGetFlow() = IntegrationFlow.from("outboundGetChannel")
    .handle(
        Http.outboundGateway("https://api.example.com/data")
            .httpMethod(HttpMethod.GET)
            .expectedResponseType(String::class.java)
    )
    .get()

发送 POST 请求

kotlin
@Bean
fun httpOutboundPostFlow() = IntegrationFlow.from("outboundPostChannel")
    .enrichHeaders { it.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) }
    .handle(
        Http.outboundGateway("https://api.example.com/submit")
            .httpMethod(HttpMethod.POST)
            .expectedResponseType(String::class.java)
    )
    .transform { response -> 
        "处理结果: ${response.substring(0, 50)}..."
    }
    .get()

注意事项

  1. 生产环境必须配置连接超时设置
  2. 建议添加重试机制处理网络波动
  3. 使用 HTTPS 时需要配置 SSL 上下文

完整示例:请求转发服务

场景说明

构建一个服务:接收客户端请求 → 转发到外部 API → 处理响应 → 返回客户端

kotlin
@SpringBootApplication
class HttpGatewayApplication

fun main(args: Array<String>) {
    runApplication<HttpGatewayApplication>(*args)
}

@RestController
class GatewayController(private val gateway: MessagingGateway) {
    
    @GetMapping("/proxy")
    fun proxyData(@RequestParam id: String): ResponseEntity<String> {
        return ResponseEntity.ok(gateway.process(id))
    }
}

interface MessagingGateway {
    @Gateway(requestChannel = "requestChannel")
    fun process(id: String): String
}

@Configuration
class ProxyIntegrationConfig {
    
    @Bean
    fun proxyFlow() = IntegrationFlow
        .from("requestChannel")
        .handle(
            Http.outboundGateway("https://external-api.com/data/{id}")
                .httpMethod(HttpMethod.GET)
                .uriVariable("id", "payload")  
                .expectedResponseType(String::class.java)
        )
        .get()
}

时序流程说明

常见问题解决方案

问题1:415 Unsupported Media Type

客户端发送了服务器无法处理的媒体类型

解决方案

kotlin
@Bean
fun httpInboundAdapter() = HttpRequestHandlingMessagingGateway(true).apply {
    setRequestMapping(
        RequestMapping().apply {
            consumes = arrayOf(MediaType.APPLICATION_JSON_VALUE) 
        }
    )
    // 其他配置...
}

问题2:连接超时

外部服务响应缓慢导致超时

解决方案

kotlin
Http.outboundGateway("https://api.example.com/data")
    .httpMethod(HttpMethod.GET)
    .expectedResponseType(String::class.java)
    .setTimeout(5000)  // 设置5秒超时

问题3:HTTPS 证书验证

自签名证书导致 SSL 握手失败

解决方案

kotlin
@Bean
fun sslContext(): SSLContext {
    val trustStore = KeyStore.getInstance(KeyStore.getDefaultType())
    FileInputStream("truststore.jks").use {
        trustStore.load(it, "password".toCharArray())
    }
    
    return SSLContextBuilder.create()
        .loadTrustMaterial(trustStore, null)
        .build()
}

最佳实践建议

  1. 使用连接池:提高 HTTP 请求性能

    kotlin
    @Bean
    fun connectionFactory(): ClientHttpRequestFactory {
        return HttpComponentsClientHttpRequestFactory().apply {
            setHttpClient(HttpClients.custom()
                .setMaxConnTotal(100)
                .setMaxConnPerRoute(20)
                .build())
        }
    }
  2. 添加全局错误处理

    kotlin
    @Bean
    fun errorChannel() = PublishSubscribeChannel().apply {
        subscribe {
            // 处理所有集成流错误
            logger.error("HTTP处理异常: ${it.payload.message}")
        }
    }
  3. 启用指标监控

    kotlin
    @Bean
    fun metricsExporter(): IntegrationManagementConfigurer {
        return IntegrationManagementConfigurer().apply {
            isDefaultLoggingEnabled = true
            setMetricsCapturer(CustomMetricsCapturer())
        }
    }

CAUTION

生产环境注意事项:

  • 必须实现请求限流
  • 添加敏感信息过滤
  • 配置合理的超时设置
  • 实施请求验证和授权

总结

Spring Integration 的 HTTP 支持提供了强大而灵活的方式处理 HTTP 通信。通过本教程,您已经学习到:

  1. ✅ 配置入站/出站 HTTP 网关
  2. ✅ 使用 Kotlin DSL 实现集成流
  3. ✅ 处理常见错误和异常
  4. ✅ 实施生产环境最佳实践

下一步建议: