【问题标题】:Content-length is null for EntityTemplateEntityTemplate 的内容长度为空
【发布时间】:2011-07-28 10:53:49
【问题描述】:

范围:我正在使用 Android 中包含的 http apache 库,并尝试通过 HttpClient 和 HttpEntity 执行 HttpPost,由 EntityTemplate 和 ContentProducer 制成。 这是代码

    HttpClient httpClient = new CustomHttpsClient().getNewHttpClient();
    HttpPost httpPost = new HttpPost("APP_URI");
    HttpEntity postEntity;
    HttpEntity getEntity;

    ContentProducer contentProducer = new ContentProducer() {

        @Override
        public void writeTo(OutputStream outstream) throws IOException {
            // TODO Auto-generated method stub
            Writer writer = new OutputStreamWriter(outstream, "UTF-8");
            writer.write("<req version=\"1.0\" lang=\"RU\">");
            writer.write("<act>o_addcard</act>");
            writer.write("</req>");
            writer.flush();
        }
    };

    postEntity = new EntityTemplate(contentProducer);
    httpPost.setEntity(postEntity);

    String responseEntity;
    try {
        HttpResponse httpResponse = httpClient.execute(httpPost);
        ...} catch(...){...}

问题:服务器总是给我411响应码(内容长度为空):

“POST / HTTP/1.1”411 180“-”“-”

这些代码适用于某些服务器。但是为什么 content-length 总是为空呢? 另外我们不能手动设置,否则会出现异常原因:

原因:org.apache.http.ProtocolException:Content-Length 标头已存在

非常感谢您的回答!

【问题讨论】:

  • 尝试访问一些标准服务器,如 www.google.com,看看你的内容长度是否为空,如果你的代码正确,你应该得到一些 html 文本作为输出。
  • Google.com 给了我 405(无论如何它拒绝发布,所以我们不能用它来检查内容长度)。我尝试了另一台服务器,它们都给了我 411。谢谢这是一个想法!但仍然没有运气......
  • 也许你应该使用 HTTpGet 方法而不是 HttpPost
  • 没有区别,411 与另一个受人尊敬的服务器的 post 方法。
  • 解决方案是使用 StringEntity 代替。我应该在这里发布我的工作代码(使用 StringEntity)作为答案吗?

标签: android apache http


【解决方案1】:

我对实体模板有同样的问题,因为它是内容长度在某些情况下没有被测量。

对我来说有两种可能的解决方法:

1) 覆盖实体模板

class EntityTemplateSpike extends EntityTemplate{

    public EntityTemplateSpike(ContentProducer contentproducer) {
        super(contentproducer);
    }

    @Override
    public long getContentLength() {
        return // Paste here your ContentLength value
    }

}
postEntity = new EntityTemplateSpike(contentProducer);

2) 错误是由标准请求拦截器 RequestContent 引起的。你可以覆盖它

    // This class is a copy of standart RequestContent class except for Exception
        // is not being thrown if ContentLegth is already set.
        private class RequestContentSpike implements HttpRequestInterceptor{
                     public RequestContentSpike() {
                         super();
                     }

                     public void  process(final HttpRequest request, final HttpContext context)  throws HttpException, IOException {
                         if (request == null) {
                             throw new IllegalArgumentException("HTTP request may not be null");
                         }

                         if (request instanceof HttpEntityEnclosingRequest) {

                             if (request.containsHeader(HTTP.TRANSFER_ENCODING)) {
                                 throw new ProtocolException("Transfer-encoding header already present");
                             }

                             ProtocolVersion ver = request.getRequestLine().getProtocolVersion();
                             HttpEntity entity = ((HttpEntityEnclosingRequest)request).getEntity();

                             if (entity == null) {
                                 request.addHeader(HTTP.CONTENT_LEN, "0");
                                 return;
                             }

                             if (entity.isChunked() || entity.getContentLength() < 0) {
                                 if (ver.lessEquals(HttpVersion.HTTP_1_0)) {
                                     throw new ProtocolException( "Chunked transfer encoding not allowed for " + ver);
                                 }
                                 request.addHeader(HTTP.TRANSFER_ENCODING, HTTP.CHUNK_CODING);
                             } else {
                                 request.addHeader(HTTP.CONTENT_LEN, Long.toString(entity.getContentLength()));
                             }


                             if (entity.getContentType() != null && !request.containsHeader(HTTP.CONTENT_TYPE )) {
                                 request.addHeader(entity.getContentType()); 
                             }


                             if (entity.getContentEncoding() != null && !request.containsHeader(HTTP.CONTENT_ENCODING)) {
                                request.addHeader(entity.getContentEncoding()); 
                            }
                        }
                    }
        }
    ((CustomHttpsClient)mClient).removeRequestInterceptorByClass(RequestContent.class);
  ((CustomHttpsClient)mClient).addRequestInterceptor(new RequestContentSpike());

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-01-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-28
    • 2012-11-03
    相关资源
    最近更新 更多