Java之HttpURLConnection的变态事: Keep-Alive
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的更多相关文章
- Java 利用HttpURLConnection发送http请求
写了一个简单的 Http 请求的Class,实现了 get, post ,postfile package com.asus.uts.util; import org.json.JSONExcepti ...
- Java你可能不知道的事(3)HashMap
概述 HashMap对于做Java的小伙伴来说太熟悉了.估计你们每天都在使用它.它为什么叫做HashMap?它的内部是怎么实现的呢?为什么我们使用的时候很多情况都是用String作为它的key呢?带着 ...
- java你可能不知道的事(2)--堆和栈
在java语言的学习和使用当中你可能已经了解或者知道堆和栈,但是你可能没有完全的理解它们.今天我们就一起来学习堆.栈的特点以及它们的区别.认识了这个之后,你可能对java有更深的理解. Java堆内存 ...
- Java使用HttpURLConnection上传文件
从普通Web页面上传文件非常easy.仅仅须要在form标签叫上enctype="multipart/form-data"就可以,剩余工作便都交给浏览器去完毕数据收集并发送Http ...
- java 通过HttpURLConnection与servlet通信
研究了一天才搞清楚,其实挺简单的,在这里记录下,以便以后参考. 一.创建一个servlet项目 主要包括(WEB-INF)里面有classes文件夹.lib文件夹.web.xml文件. 将写好的ser ...
- Java Socket/HttpURLConnection读取HTTP网页
以读取百度的http网页为例.如果知道了IP地址和端口,然后新建一个Socket,就直接去读百度的首页,根本没反应,原因是www.baidu.com是以http协议传输的,而现在要以Socket原始的 ...
- java 利用HttpURLConnection方式获取restful格式的服务数据
/** * @Author: * @Description:利用HttpURLConnection方式获取restful格式的服务数据 * @Date: */ private static List& ...
- java你可能不知道的事(2)--堆和栈<转>
在java语言的学习和使用当中你可能已经了解或者知道堆和栈,但是你可能没有完全的理解它们.今天我们就一起来学习堆.栈的特点以及它们的区别.认识了这个之后,你可能对java有更深的理解. Java堆内存 ...
- Android(或者Java)通过HttpUrlConnection向SpringMVC请求数据(数据绑定)
问题描写叙述 当我们使用SpringMVC作为服务端的框架时,有时不仅仅要应对web前端(jsp.javascript.Jquery等)的訪问请求,有时还可能须要响应Android和JavaSE(桌面 ...
随机推荐
- OpenJudge 核电站
描述 一个核电站有N个放核物质的坑,坑排列在一条直线上.如果连续M个坑中放入核物质,则会发生爆炸,于是,在某些坑中可能不放核物质. 任务:对于给定的N和M,求不发生爆炸的放置核物质的方案总数 输入 只 ...
- 图的最短路算法 Dijkstra及其优化
单源最短路径算法 时间复杂度O(N2) 优化后时间复杂度为O(MlogN)(M为图中的边数 所以对于稀疏图来说优化后更快) 不支持有负权的图 #include<iostream> usin ...
- javascript设计模式-外观模式
也可译为门面模式.它为子系统中的一组接口提供一个一致的界面, Facade模式定义了一个高层接口,这个接口使得这一子系统更加容易使用.引入外观角色之后,使用者只需要直接与外观角色交互,使用者与子系统之 ...
- Ossim主要功能实战
Ossim主要功能实战 OSSIM通过将开源产品进行集成,从而提供一种能够实现安全监控功能的基础平台将Nagiso,Ntop,Snort,Nmap等开源工具集成在一起提供综合的安全保护功能,而不必在各 ...
- [转]回答--python django学的很迷茫怎么办?
作者:王一链接:http://www.zhihu.com/question/26235428/answer/36568428来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处 ...
- C#多线程案例基础
C#多线程案例基础(转) 在学习多线程之前,我们先来看几个概念: 1,什么是进程? 当一个程序开始运行时,它就是一个进程,进程包括运行中的程序和程序所使用到的内存和系统资源,当然一个程序也可能开 ...
- form提交时,传递额外的参数
在进行表单提交时,会遇到在提交前增加额外参数的情况,对此有如下几种解决方法: 1. 在表单里使用hidden的input,将参数放到里面. 缺点:在form表单里会增加一些input节点,感觉不爽. ...
- 理解DOM中的事件流
浏览器发展到第四代时(IE4和Netscape Communicator 4),浏览器团队遇到一个很有意思的问题:页面的哪一部分会拥有特定的事件?想象下在一张纸上有一组同心圆,如果你把手指放在圆心上, ...
- Android IOS WebRTC 音视频开发总结(三九)-- win10升级为何要p2p
本文主要介绍webrtc p2p的应用场景,文章来自博客园RTC.Blacker,支持原创,转载请说明出处. P2P最简单的解释就是两个客户端之间直接进行数据交互,不经过服务端转发. 最早接触P2P是 ...
- Jquery调用Webservice传递Json数组
Jquery由于提供的$.ajax强大方法,使得其调用webservice实现异步变得简单起来,可以在页面上传递Json字符串到Webservice中,Webservice方法进行业务处理后,返回Js ...