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

Spring Integration4:Http Outbound Gateway的RestTemplate覆盖Accept头问题求助

问题原因分析

从你的日志细节里能发现矛盾点:

  • DefaultHttpHeaderMapper已经正确把Accept头设置为application/vnd.dsths.services-v8+xml
  • 但紧接着RestTemplate又将Accept头重置成了默认的[text/plain, application/json, application/*+json, */*]

这是Spring Integration 4中HttpOutboundGateway的一个特性:当你指定expected-response-type="java.lang.String"时,RestTemplate会根据这个响应类型自动匹配对应的HttpMessageConverter(这里是StringHttpMessageConverter),然后用该转换器默认支持的媒体类型覆盖之前通过HeaderMapper设置的Accept头。而StringHttpMessageConverter默认支持的媒体类型正好是日志里显示的那几个,所以你的自定义Accept头被覆盖,导致服务端因接收不符合要求的请求头返回400错误。

解决方案

这里提供两种可行的解决思路:

方式一:自定义RestTemplate,修改消息转换器的支持类型

创建一个自定义的RestTemplate,调整StringHttpMessageConverter仅支持你需要的媒体类型,这样RestTemplate就不会自动生成默认的Accept头了。

配置示例:

<!-- 自定义RestTemplate,指定String转换器支持的媒体类型 -->
<bean id="customRestTemplate" class="org.springframework.web.client.RestTemplate">
    <property name="messageConverters">
        <list>
            <bean class="org.springframework.http.converter.StringHttpMessageConverter">
                <property name="supportedMediaTypes">
                    <list>
                        <value>application/vnd.dsths.services-v8+xml</value>
                    </list>
                </property>
            </bean>
            <!-- 如果需要处理其他类型的响应,比如JSON,记得添加对应的转换器 -->
            <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/>
        </list>
    </property>
</bean>

<!-- 出站网关引用自定义RestTemplate -->
<int-http:outbound-gateway url-expression="headers.restResourceUrl" 
                           http-method-expression="headers.httpMethod" 
                           expected-response-type="java.lang.String"
                           rest-template="customRestTemplate">
</int-http:outbound-gateway>

方式二:移除expected-response-type,通过下游处理器转换响应

如果场景允许,可以不指定expected-response-type,让响应以ResponseEntity形式返回,这样RestTemplate不会自动覆盖Accept头。之后在下游消息处理器中将响应体转换成String类型。

调整后的配置示例:

<int-http:outbound-gateway url-expression="headers.restResourceUrl" 
                           http-method-expression="headers.httpMethod" 
                           expected-response-type="org.springframework.http.ResponseEntity"
                           reply-channel="responseProcessingChannel">
</int-http:outbound-gateway>

<!-- 下游处理器:将ResponseEntity的body转换为String -->
<int:service-activator input-channel="responseProcessingChannel" ref="responseHandler" method="processResponse"/>

<bean id="responseHandler" class="your.package.ResponseHandler"/>

对应的处理器类示例:

public class ResponseHandler {
    public String processResponse(ResponseEntity<byte[]> response) {
        if (response.getStatusCode().is2xxSuccessful()) {
            return new String(response.getBody(), StandardCharsets.UTF_8);
        }
        // 处理错误场景
        throw new RuntimeException("请求失败,状态码:" + response.getStatusCode());
    }
}

验证要点

修改完成后,重新查看日志,确认RestTemplate不再重置Accept头,而是保留你自定义的application/vnd.dsths.services-v8+xml,此时应该就能解决400错误了。

内容的提问来源于stack exchange,提问作者Ashok.N

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:23:07