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

使用request-factory的http:outbound-gateway能否集成ClientHttpRequestInterceptor做日志?

解决方案

你不需要子类化HttpComponentsClientHttpRequestFactory,ClientHttpRequestInterceptor方案依然可行,只需要调整配置方式,把请求工厂和拦截器整合到RestTemplate中,再将该RestTemplate配置到http:outbound-gateway即可。

方案一:通过RestTemplate整合Spring拦截器

这种方式保留Spring生态的拦截器模型,同时复用Apache HttpClient的配置:

  1. 定义HttpComponentsClientHttpRequestFactory Bean:
<bean id="httpRequestFactory" class="org.springframework.http.client.HttpComponentsClientHttpRequestFactory">
    <!-- 配置Apache HttpClient参数,比如连接池、超时时间等 -->
</bean>
  1. 实现自定义的ClientHttpRequestInterceptor日志拦截器:
public class LoggingClientHttpRequestInterceptor implements ClientHttpRequestInterceptor {
    private static final Logger logger = LoggerFactory.getLogger(LoggingClientHttpRequestInterceptor.class);

    @Override
    public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
        // 记录请求信息:URL、方法、请求体、头信息等
        logger.info("Outbound HTTP Request: {} {} | Headers: {} | Body: {}",
                request.getMethod(), request.getURI(), request.getHeaders(), new String(body, StandardCharsets.UTF_8));
        
        ClientHttpResponse response = execution.execute(request, body);
        
        // 记录响应信息:状态码、响应体、头信息等
        String responseBody = StreamUtils.copyToString(response.getBody(), StandardCharsets.UTF_8);
        logger.info("Inbound HTTP Response: {} | Headers: {} | Body: {}",
                response.getStatusCode(), response.getHeaders(), responseBody);
        
        return response;
    }
}
  1. 定义带有拦截器的RestTemplate,注入请求工厂:
<bean id="loggingRestTemplate" class="org.springframework.web.client.RestTemplate">
    <constructor-arg ref="httpRequestFactory"/>
    <property name="interceptors">
        <list>
            <bean class="com.yourpackage.LoggingClientHttpRequestInterceptor"/>
        </list>
    </property>
</bean>
  1. 在http:outbound-gateway中配置该RestTemplate:
<int-http:outbound-gateway id="outboundGateway"
                           request-channel="requestChannel"
                           url="http://your-target-api-url"
                           rest-template="loggingRestTemplate"
                           <!-- 其他网关配置属性 -->/>

方案二:使用Apache HttpClient原生拦截器

如果更倾向于直接操作Apache HttpClient的底层流程,可以给HttpClient实例添加原生的HttpRequestInterceptor:

  1. 实现Apache HttpClient的HttpRequestInterceptor:
public class ApacheHttpRequestLoggingInterceptor implements HttpRequestInterceptor {
    private static final Logger logger = LoggerFactory.getLogger(ApacheHttpRequestLoggingInterceptor.class);

    @Override
    public void process(HttpRequest request, HttpContext context) throws HttpException, IOException {
        // 记录请求信息
        if (request instanceof HttpEntityEnclosingRequest) {
            HttpEntityEnclosingRequest entityRequest = (HttpEntityEnclosingRequest) request;
            String body = EntityUtils.toString(entityRequest.getEntity(), StandardCharsets.UTF_8);
            logger.info("Outbound Apache HTTP Request: {} {} | Headers: {} | Body: {}",
                    request.getRequestLine().getMethod(), request.getRequestLine().getUri(),
                    request.getAllHeaders(), body);
        } else {
            logger.info("Outbound Apache HTTP Request: {} {} | Headers: {}",
                    request.getRequestLine().getMethod(), request.getRequestLine().getUri(),
                    request.getAllHeaders());
        }
    }
}
  1. 配置带有拦截器的HttpClient实例,注入到请求工厂:
<bean id="apacheLoggingInterceptor" class="com.yourpackage.ApacheHttpRequestLoggingInterceptor"/>

<bean id="customHttpClient" class="org.apache.http.impl.client.HttpClients" factory-method="custom">
    <constructor-arg>
        <bean class="org.apache.http.impl.client.HttpClientBuilder">
            <method name="addInterceptorFirst">
                <ref bean="apacheLoggingInterceptor"/>
            </method>
            <!-- 配置HttpClient参数,比如连接池、超时等 -->
        </bean>
    </constructor-arg>
</bean>

<bean id="httpRequestFactory" class="org.springframework.http.client.HttpComponentsClientHttpRequestFactory">
    <property name="httpClient" ref="customHttpClient"/>
</bean>
  1. 在http:outbound-gateway中使用该请求工厂:
<int-http:outbound-gateway id="outboundGateway"
                           request-channel="requestChannel"
                           url="http://your-target-api-url"
                           request-factory="httpRequestFactory"
                           <!-- 其他网关配置属性 -->/>

两种方案都能实现HTTP请求/响应的日志记录,你可以根据自己的技术习惯选择。

内容的提问来源于stack exchange,提问作者al.truisme

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 02:25:17