HttpClient: Content-Length header already present解决及分析

快来打我* 2023-06-16 02:22 62阅读 0赞

在用HttpClient的时候出现如下问题:

  1. org.apache.http.client.ClientProtocolException
  2. at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:822)
  3. at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:754)
  4. at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:732)
  5. ……
  6. Caused by: org.apache.http.ProtocolException: Content-Length header already present
  7. at org.apache.http.protocol.RequestContent.process(RequestContent.java:67)
  8. at org.apache.http.protocol.ImmutableHttpProcessor.process(ImmutableHttpProcessor.java:108)
  9. at org.apache.http.protocol.HttpRequestExecutor.preProcess(HttpRequestExecutor.java:174)
  10. at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:462)
  11. at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:820)
  12. ... 27 more
  • 出现上面的问题是发送请求的时候设置了请求头Content-Length参数。
  • 解决办法:把设置的请求头Content-Length参数去掉。
  • 分析原因:
    跟踪代码:查看HttpClient中RequestContent类的process方法,看到当body非空时,会自动加上Content-Length请求头及其对应值,不需要自己手动加上它。加上就会抛出上面的异常。
    源码:

    public class RequestContent implements HttpRequestInterceptor {

    1. private final boolean overwrite;
    2. public RequestContent() {
    3. this(false);
    4. }
    5. public RequestContent(boolean overwrite) {
    6. this.overwrite = overwrite;
    7. }
    8. public void process(HttpRequest request, HttpContext context) throws HttpException, IOException {
    9. Args.notNull(request, "HTTP request");
    10. if (request instanceof HttpEntityEnclosingRequest) {
    11. if (this.overwrite) {
    12. request.removeHeaders("Transfer-Encoding");
    13. request.removeHeaders("Content-Length");
    14. } else {
    15. if (request.containsHeader("Transfer-Encoding")) {
    16. throw new ProtocolException("Transfer-encoding header already present");
    17. }
    18. if (request.containsHeader("Content-Length")) {
    19. throw new ProtocolException("Content-Length header already present");
    20. }
    21. }
    22. ProtocolVersion ver = request.getRequestLine().getProtocolVersion();
    23. HttpEntity entity = ((HttpEntityEnclosingRequest)request).getEntity();
    24. if (entity == null) {
    25. request.addHeader("Content-Length", "0");
    26. return;
    27. }
    28. if (!entity.isChunked() && entity.getContentLength() >= 0L) {
    29. //计算请求头的长度
    30. request.addHeader("Content-Length", Long.toString(entity.getContentLength()));
    31. } else {
    32. if (ver.lessEquals(HttpVersion.HTTP_1_0)) {
    33. throw new ProtocolException("Chunked transfer encoding not allowed for " + ver);
    34. }
    35. request.addHeader("Transfer-Encoding", "chunked");
    36. }
    37. if (entity.getContentType() != null && !request.containsHeader("Content-Type")) {
    38. request.addHeader(entity.getContentType());
    39. }
    40. if (entity.getContentEncoding() != null && !request.containsHeader("Content-Encoding")) {
    41. request.addHeader(entity.getContentEncoding());
    42. }
    43. }
    44. }

    }

发表评论

表情:
评论列表 (有 0 条评论,62人围观)

还没有评论,来说两句吧...

相关阅读