Content-Length 标头已存在

新手上路,请多包涵

我正在使用 Android 中包含的 Apache HttpClient (4.1) 来执行 HttpPut。我已验证我只有 1 个内容长度标头。但是,每次发送请求时,我都会收到有关已指定的 Content-Length 标头的协议异常。

 HttpClient client = new DefaultHttpClient();
putMethod = new HttpPut(url + encodedFileName);
putMethod.addHeader(..)  //<-once for each header
putMethod.setEntity(new ByteArrayEntity(data));
client.execute(putMethod);  //throws Exception

由以下原因引起:org.apache.http.ProtocolException:Content-Length header already present at org.apache.http.protocol.RequestContent.process(RequestContent.java:70) at org.apache.http.protocol.BasicHttpProcessor.process(BasicHttpProcessor .java:290)

有任何想法吗?

原文由 AdamC 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.4k
2 个回答

我自己没有使用过 HttpClient,但我怀疑问题在于 putMethod.setEntity(...) 隐式提供了内容长度,并且您还通过 putMethod.addHeader(...) 调用之一显式设置了它。

原文由 Stephen C 发布,翻译遵循 CC BY-SA 2.5 许可协议

正如 igor.zh 所指出的,如果使用 Spring 的 HttpComponentsMessageSender 类,就会出现此问题。更准确地说,如果您将自己的 HttpClient 实例传递到 HttpComponentsMessageSender 构造函数中,这只是一个问题 - 否则该问题会自动处理。

从 spring-ws 2.1.4 开始,默认构造函数中使用的 HttpComponentsMessageSender.RemoveSoapHeadersInterceptor 子类已公开以解决此问题(请参阅 https://jira.spring.io/browse/SWS-835 ),因此可以在您自己的 HttpClient 实例中使用,而不是编写您自己的类来执行此操作。它还会清除 HTTP.TRANSFER_ENCODING 标头。

使用 HttpClientBuilder.addInterceptorFirst 方法将此拦截器注入您自己的 HttpClient 实例。下面的示例使用 XML bean 连接。如果有人知道构造 HttpClient 实例的更简洁的方法(除了编写工厂 bean 类之外),我洗耳恭听!

 <bean id="httpClientBuilder" class="org.apache.http.impl.client.HttpClientBuilder" factory-method="create"/>

<bean id="interceptedHttpClientBuilder" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
    <property name="targetObject" ref="httpClientBuilder" />
    <property name="targetMethod" value="addInterceptorFirst"> </property>
    <property name="arguments">
        <list>
            <bean class="org.springframework.ws.transport.http.HttpComponentsMessageSender.RemoveSoapHeadersInterceptor"/>
        </list>
    </property>
</bean>

<bean id="httpClient" factory-bean="interceptedHttpClientBuilder" factory-method="build" />

<bean id="webServiceTemplate" class="org.springframework.ws.client.core.WebServiceTemplate">
    <constructor-arg ref="messageFactory"/>
    <property name="messageSender">
        <bean class="org.springframework.ws.transport.http.HttpComponentsMessageSender">
            <property name="httpClient" ref="httpClient"/>
        </bean>
    </property>
</bean>

或者,如果可以,只允许 HttpComponentsMessageSender 构造自己的 HttpClient 实例,而不是将一个实例传递给它。关于此的小说明:从 spring-ws 2.2.0-RELEASE 开始,HttpComponentsMessageSender 的默认构造函数继续使用 DefaultHttpClient 类,该类现已弃用。希望这将在未来的版本中得到解决。

原文由 John Rix 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题