java应用程序:httpclient如何实现在一个连接中发送多次 请求?
如题,最好能给个简单的demo,几行也可以,就是核心的在一个连接中允许多次发送请求的代码!谢谢各位了!我用的连接池,如下,就是想实现多次调用post均使用同一个打开的连接,如何实现?测试发现老是会重新建立连接(即新开端口进行通信)!
public class HttpClientTestDemo {
public static final int MAX_TOTAL_CONNECTIONS = 400;
public static final int MAX_ROUTE_CONNECTIONS = 100;
public static final int CONNECT_TIMEOUT = 10000;
public static final int SOCKET_TIMEOUT = 20000;
public static final long CONN_MANAGER_TIMEOUT = 10000;
public static HttpParams parentParams;
public static PoolingClientConnectionManager cm;
private static final HttpHost DEFAULT_TARGETHOST = new HttpHost("123.456.789.101", 80);
public static HttpRequestRetryHandler httpRequestRetryHandler;
static {
SchemeRegistry schemeRegistry = new SchemeRegistry();
schemeRegistry.register(
new Scheme("http", 80, PlainSocketFactory.getSocketFactory()));
schemeRegistry.register(
new Scheme("https", 443, SSLSocketFactory.getSocketFactory()));
cm = new PoolingClientConnectionManager(schemeRegistry);
cm.setMaxTotal(MAX_TOTAL_CONNECTIONS);
cm.setDefaultMaxPerRoute(MAX_ROUTE_CONNECTIONS);
cm.setMaxPerRoute(new HttpRoute(DEFAULT_TARGETHOST), 20);
parentParams = new BasicHttpParams();
parentParams.setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);
parentParams.setParameter(ClientPNames.DEFAULT_HOST, DEFAULT_TARGETHOST); //设置默认targetHost
parentParams.setParameter(ClientPNames.COOKIE_POLICY, CookiePolicy.BROWSER_COMPATIBILITY);
parentParams.setParameter(ClientPNames.CONN_MANAGER_TIMEOUT, CONN_MANAGER_TIMEOUT);
parentParams.setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, CONNECT_TIMEOUT);
parentParams.setParameter(CoreConnectionPNames.SO_TIMEOUT, SOCKET_TIMEOUT);
parentParams.setParameter(ClientPNames.ALLOW_CIRCULAR_REDIRECTS, true);
parentParams.setParameter(ClientPNames.HANDLE_REDIRECTS, true);
//设置头信息,模拟浏览器
Collection collection = new ArrayList();
collection.add(new BasicHeader("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)"));
collection.add(new BasicHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"));
collection.add(new BasicHeader("Accept-Language", "zh-cn,zh,en-US,en;q=0.5"));
collection.add(new BasicHeader("Accept-Charset", "ISO-8859-1,utf-8,gbk,gb2312;q=0.7,*;q=0.7"));
collection.add(new BasicHeader("Accept-Encoding", "gzip, deflate"));
parentParams.setParameter(ClientPNames.DEFAULT_HEADERS, collection);
//请求重试处理
httpRequestRetryHandler = new HttpRequestRetryHandler() {
@Override
public boolean retryRequest(IOException exception, int executionCount, HttpContext context) {
if (executionCount >= 3) {
// 如果超过最大重试次数,那么就不要继续了
return false;
}
if (exception instanceof NoHttpResponseException) {
// 如果服务器丢掉了连接,那么就重试
return true;
}
if (exception instanceof SSLHandshakeException) {
// 不要重试SSL握手异常
return false;
}
HttpRequest request = (HttpRequest) context.getAttribute(ExecutionContext.HTTP_REQUEST);
boolean idempotent = !(request instanceof HttpEntityEnclosingRequest);
if (idempotent) {
// 如果请求被认为是幂等的,那么就重试
return true;
}
return false;
}
};
}
private static String readHtmlContentFromEntity(HttpEntity httpEntity) throws ParseException, IOException {
String html = "";
Header header = httpEntity.getContentEncoding();
{
InputStream in = httpEntity.getContent();
if (header != null && "gzip".equals(header.getValue())) {
html = unZip(in);
} else {
html = readInStreamToString(in);
}
if (in != null) {
in.close();
}
}
return html;
}
private static String unZip(InputStream in) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
GZIPInputStream gis = null;
try {
gis = new GZIPInputStream(in);
byte[] _byte = new byte[1024];
int len = 0;
while ((len = gis.read(_byte)) != -1) {
baos.write(_byte, 0, len);
}
String unzipString = new String(baos.toByteArray(), "utf-8");
return unzipString;
} finally {
if (gis != null) {
gis.close();
}
if (baos != null) {
baos.close();
}
if(in!=null)
{
in.close();
}
}
}
private static String readInStreamToString(InputStream in) throws IOException {
StringBuilder str = new StringBuilder();
String line;
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(in, "utf-8"));
while ((line = bufferedReader.readLine()) != null) {
str.append(line);
str.append("\r\n");
}
if (bufferedReader != null) {
bufferedReader.close();
}
if(in!=null)
in.close();
return str.toString();
}
public static String post(DefaultHttpClient httpClient, String url) throws UnsupportedEncodingException {
HttpGet httpGet = new HttpGet(url);
String result = "";
httpGet.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, DEFAULT_TARGETHOST);
HttpResponse httpResponse;
try {
httpResponse = httpClient.execute(httpGet);//建立端口映射
if (httpResponse.getStatusLine().getStatusCode() != 200) {
httpGet.abort();
return result;
}
result = readHtmlContentFromEntity(httpResponse.getEntity());
} catch (ClientProtocolException e) {
httpGet.abort();
return e.toString();
} catch (IOException ex) {
httpGet.abort();
return ex.toString();
} finally {
httpGet.releaseConnection();
httpClient.close();
}
return result;
}
public static void main(String[] args) throws InterruptedException {
Date start = new Date();
DefaultHttpClient httpClient = new DefaultHttpClient(cm, parentParams);
httpClient.setHttpRequestRetryHandler(httpRequestRetryHandler);
try {
post(httpClient, "https://www.baidu.com/index1.php");//这里的几个网址是随便举例的,实际页面是纯txt,没有任何其他元素
post(httpClient, "https://www.baidu.com/index2.php");
post(httpClient, "https://www.baidu.com/index3.php");
} catch (UnsupportedEncodingException ex) {
Logger.getLogger(HttpClientTestDemo.class.getName()).log(Level.SEVERE, null, ex);
}
Date end = new Date();
System.out.println((end.getTime() - start.getTime()) / 1000.0 + " 秒");
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
注释掉
我也想知道!大批量的请求重用已有连接的问题!
为什么都没有人回答呢?真的急用呀!解决得好的话有福利哟!
应该只能走KeepAlive了