HttpURLConnection的变态事: Keep-Alive

JDK自带的HttpURLConnection默认启动Keep-Alive, 使用后的HttpURLConnection会放入池里重用. 相关描述:

What does the current JDK do for Keep-Alive?

The JDK supports both HTTP/1.1 and HTTP/1.0 persistent connections.

When the application finishes reading the response body or when the application calls close() on the InputStream returned by URLConnection.getInputStream(), the JDK's HTTP protocol handler will try to clean up the connection and if successful, put the connection into a connection cache for reuse by future HTTP requests.

The support for HTTP keep-Alive is done transparently. However, it can be controlled by system properties http.keepAlive, and http.maxConnections, as well as by HTTP/1.1 specified request and response headers.

The system properties that control the behavior of Keep-Alive are:

http.keepAlive=<boolean>
default: true

Indicates if keep alive (persistent) connections should be supported.

http.maxConnections=<int>
default: 5

Indicates the maximum number of connections per destination to be kept alive at any given time

HTTP header that influences connection persistence is:

Connection: close

If the "Connection" header is specified with the value "close" in either the request or the response header fields, it indicates that the connection should not be considered 'persistent' after the current request/response is complete.

The current implementation doesn't buffer the response body. Which means that the application has to finish reading the response body or call close() to abandon the rest of the response body, in order for that connection to be reused. Furthermore, current implementation will not try block-reading when cleaning up the connection, meaning if the whole response body is not available, the connection will not be reused.

如果服务端不支持Keep-Alive, 这种默认行为就会带来很多蛋疼的事, 举个例子:

mogilefs服务端默认没有启用Keep-Alive. 使用HttpURLConnection上传多个文件时, 由于Keep-Alive这种重用特性,导致for循环中第一个文件后的其实PUT请求卡死! 直到Socket Request Timeout! 这种行为实在很变态!

解决办法在上面描述已经提及, 经测试, 完成可行:
(1)System.setProperty("http.keepAlive", String.valueOf(false));
(2)conn.setRequestProperty("Connection", "close");
根据个人兴趣选择其一即可.

以下是mogilefs上传多个文件的实现(其实就是HttpURLConnection的PUT请求):

public static String upload(String uri, int size, InputStream content) throws DfsClientException, MalformedURLException, IOException {

HttpURLConnection conn = null;
  try {
   conn = (HttpURLConnection) new URL(uri).openConnection();
   System.out.println(conn.hashCode());
   conn.setFixedLengthStreamingMode(size);

conn.setUseCaches(false);
   conn.setDoInput(true);
   conn.setDoOutput(true);
   conn.setConnectTimeout(1000);
   conn.setReadTimeout(2000);
   conn.setRequestMethod("PUT");
   //System.setProperty("http.keepAlive", String.valueOf(false));
   conn.setRequestProperty("Connection", "close");

conn.connect();

System.out.println(conn.usingProxy());
   OutputStream out = conn.getOutputStream();
   for (int bt = 0; (bt = content.read()) != -1;) {
    out.write(bt);
   }
   out.close();

int code = conn.getResponseCode();
   StringBuilder sb = new StringBuilder();
   InputStream in = conn.getErrorStream();
   if (in == null) {
    in = conn.getInputStream();
   }
   if (in != null) {
    BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
    for (String line = null; (line = reader.readLine()) != null;) {
     sb.append(line);
    }
    reader.close();
   }

System.out.format("RESP[%d] %s", code, sb);
   System.out.println(uri);
  } finally {
   if (conn != null) {
    conn.disconnect();
   }
  }

return uri.replace("/upload", "/download");
}

Java之HttpURLConnection的变态事: Keep-Alive的更多相关文章

  1. Java 利用HttpURLConnection发送http请求

    写了一个简单的 Http 请求的Class,实现了 get, post ,postfile package com.asus.uts.util; import org.json.JSONExcepti ...

  2. Java你可能不知道的事(3)HashMap

    概述 HashMap对于做Java的小伙伴来说太熟悉了.估计你们每天都在使用它.它为什么叫做HashMap?它的内部是怎么实现的呢?为什么我们使用的时候很多情况都是用String作为它的key呢?带着 ...

  3. java你可能不知道的事(2)--堆和栈

    在java语言的学习和使用当中你可能已经了解或者知道堆和栈,但是你可能没有完全的理解它们.今天我们就一起来学习堆.栈的特点以及它们的区别.认识了这个之后,你可能对java有更深的理解. Java堆内存 ...

  4. Java使用HttpURLConnection上传文件

    从普通Web页面上传文件非常easy.仅仅须要在form标签叫上enctype="multipart/form-data"就可以,剩余工作便都交给浏览器去完毕数据收集并发送Http ...

  5. java 通过HttpURLConnection与servlet通信

    研究了一天才搞清楚,其实挺简单的,在这里记录下,以便以后参考. 一.创建一个servlet项目 主要包括(WEB-INF)里面有classes文件夹.lib文件夹.web.xml文件. 将写好的ser ...

  6. Java Socket/HttpURLConnection读取HTTP网页

    以读取百度的http网页为例.如果知道了IP地址和端口,然后新建一个Socket,就直接去读百度的首页,根本没反应,原因是www.baidu.com是以http协议传输的,而现在要以Socket原始的 ...

  7. java 利用HttpURLConnection方式获取restful格式的服务数据

    /** * @Author: * @Description:利用HttpURLConnection方式获取restful格式的服务数据 * @Date: */ private static List& ...

  8. java你可能不知道的事(2)--堆和栈<转>

    在java语言的学习和使用当中你可能已经了解或者知道堆和栈,但是你可能没有完全的理解它们.今天我们就一起来学习堆.栈的特点以及它们的区别.认识了这个之后,你可能对java有更深的理解. Java堆内存 ...

  9. Android(或者Java)通过HttpUrlConnection向SpringMVC请求数据(数据绑定)

    问题描写叙述 当我们使用SpringMVC作为服务端的框架时,有时不仅仅要应对web前端(jsp.javascript.Jquery等)的訪问请求,有时还可能须要响应Android和JavaSE(桌面 ...

随机推荐

  1. 在java 中,数组与 List<T> 类型的相互转换

    在java中,数组与List<T> 之前进行互相转换,转换方法可总结为以下几种: 一. 将 数组转换成List<T> 1. 使用 Collections 的addAll 方法 ...

  2. 二叉树删除 lisp

    ;;; From ANSI Common Lisp ; If you have questions or comments about this code, or you want; somethin ...

  3. new 、operator new 和 placement new

    一.原生operator new 我们先从原生operator new开始.考虑如下代码,它用来分配5个int型的空间并返回指向他们的指针[1]: int* v = static_cast<in ...

  4. MFC TOOLBAR

    m_imagelist.Create(,,ILC_COLOR24|ILC_MASK,,); CBitmap bmp; ;i<;i++) { int a= bmp.LoadBitmapW(IDB_ ...

  5. WP8_定位新页面中listbox的某项

    即将跳转到页面A,在页面A中有一个listbox,在跳转的时候,接收参数,自动选中listbox中的某项 /// <summary> /// 接收参数,定位当前选中项 /// </s ...

  6. Track files and folders manipulation in Windows

    The scenario is about Business Secret and our client do worry about data leakage. They want to know ...

  7. SID与GUID的区别

    1.在AD里面创建一个用户或者组都会为其分配一个SID,同时也会为这些对象分配一个GUID,GUID是一个128位的字符串,一个标识符,GUID不仅在整个域里面是唯一的,并且在全世界的范围内都是唯一的 ...

  8. Python之路【第五篇】:面向对象及相关

    Python之路[第五篇]:面向对象及相关   面向对象基础 基础内容介绍详见一下两篇博文: 面向对象初级篇 面向对象进阶篇 其他相关 一.isinstance(obj, cls) 检查是否obj是否 ...

  9. 线性回归的Spark实现 [Linear Regression / Machine Learning / Spark]

    1- 问题提出 2- 线性回归 3- 理论推导 4- Python/Spark实现 # -*- coding: utf-8 -*- from pyspark import SparkContext t ...

  10. SpringMVC与HTML页面

    springMVC返回html页面 spring-mvc.xml配置: <bean id="viewResolver"  class="org.springfram ...