首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Content-Length标头已存在

Content-Length标头已存在
EN

Stack Overflow用户
提问于 2010-07-26 13:21:20
回答 6查看 39.8K关注 0票数 37

我正在使用Android中包含的Apache HttpClient (4.1)来执行HttpPut。我已经确认我只有1个content-length报头。但是,每次我发送请求时,都会收到一个关于已经指定的Content-Length报头的协议异常。

代码语言:javascript
复制
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.protocol.BasicHttpProcessor.process(BasicHttpProcessor.java:290)的org.apache.http.protocol.RequestContent.process(RequestContent.java:70)中已存在的org.apache.http.ProtocolException: Content-Length标头

有什么想法吗?

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2010-07-26 13:50:23

我自己没有使用过HttpClient,但我怀疑问题出在putMethod.setEntity(...)隐式地提供了一个内容长度,而您也是通过一个putMethod.addHeader(...)调用显式地设置了它。

票数 33
EN

Stack Overflow用户

发布于 2015-03-11 20:21:35

正如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类之外),我洗耳恭听!

代码语言:javascript
复制
<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类,该类现在已被弃用。希望这将在未来的版本中得到解决。

票数 45
EN

Stack Overflow用户

发布于 2014-06-07 03:51:53

当我使用http://docs.spring.io/spring-ws/site/apidocs/org/springframework/ws/transport/http/HttpComponentsMessageSender.html作为Spring WebService消息发送器时,就会发生这种情况。在这种情况下,像HttpPut或HttpRequest这样的东西是不容易访问的,所以,在用HttpClientBuilder构建HttpClient时,我最终在罪魁祸首RequestContent前面插入了一个HttpRequestInterceptor:

代码语言:javascript
复制
private static class ContentLengthHeaderRemover implements HttpRequestInterceptor{
    @Override
    public void process(HttpRequest request, HttpContext context) throws HttpException, IOException {
        request.removeHeaders(HTTP.CONTENT_LEN);// fighting org.apache.http.protocol.RequestContent's ProtocolException("Content-Length header already present");
    }
}
...
    HttpClientBuilder httpClientBuilder = HttpClients.custom();
    httpClientBuilder.addInterceptorFirst(new CcontentLengthHeaderRemover());
票数 15
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3332370

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档