annotation与HttpClient(1)--HttpClient简介

HttpClient使用方法

本文是个人见解,有不到的地方请批评指正

HttpClient作为访问Http服务的客户端访问程序已经被广泛使用,对于HttpClient的使用方法也有很多blog进行介绍,本文简明扼要的介绍HttpClient的两种使用方式——简单连接管理的HttpClient(BasicClientConnectionManager)和池化的HttpClient(PoolingClientConnectionManager)。

HttpClient从4.2开始抛弃了先前的SingleClientConnManager和ThreadSafeConnManger,取而代之的是BasicClientConnectionManager和PoolingClientConnectionManager。

BasicClientConnectionManager内部只维护一个活动的connection,尽管这个类是线程安全的,但是最好在一个单独的线程中重复使用它。如果在同一个BasicClientConnectionManager对象中,多次执行http请求,后继请求与先前请求是同一个route,那么BasicClientConnectionManager会使用同一个连接完成后续请求,否则,BasicClientConnectionManager会将先前的connection关闭,然后为后续请求创建一个新的连接。换句话说,BasicClientConnectionManager会尽力复用先前的连接(注意:创建连接和销毁连接都是不小的开销),因此,如果对同一个service有多个连续请求,应该尽量使用同一个BasicClientConnectionManager完成。

PoolingClientConnectionManager可以在多线程中使用,连接按照route被缓存(pooled),当后续的请求route已经在pool中存在,就会使用pool中先前使用的connection获取请求结果。PoolingClientConnectionManager对每个router维护的connection数目有上限要求,默认情况下,每个router最多维护两个并发线程的connection连接,整个pool最多容纳20个并发的connections。当然可以通过设置来修改这些限制。

下面给出两个例子:

Demo 1:BasicClientConnectionManager

    public static void basicClientTest() throws ClientProtocolException,IOException{

       HttpClient httpClient = new DefaultHttpClient();

       HttpGet httpGet = new HttpGet("http://m.weather.com.cn/data/101010100.html");

       HttpResponse response = httpClient.execute(httpGet);

       String result = EntityUtils.toString(response.getEntity(),Charset.forName("utf-8"));

       System.out.println(result);

       httpClient.getConnectionManager().shutdown();

    }

Demo1中,使用最简单的方式创建的httpclient内部使用的是BasicClientConnectionManager管理连接,并且使用HttpClient提供的EntityUtils将消息体转换成String输出。httpClient对象可以被重复使用,执行多个http请求,当你真正不需要他的时候,记得调用shutdown,关闭并且释放占用的资源。

Demo2:PoolingClientConnectionManager

    public static void httpclientPool()throws ClientProtocolException, IOException{

       SchemeRegistry registry = new SchemeRegistry();//创建schema

      

       SSLContext sslContext = null;//https类型的消息访问

       try{

           sslContext = SSLContext.getInstance("SSL");

           sslContext.init(null, null, null);

       }

       catch (Exception e) {

           e.printStackTrace();

       }

       SSLSocketFactory sslFactory = newSSLSocketFactory(sslContext,SSLSocketFactory.STRICT_HOSTNAME_VERIFIER);

       registry.register(new Scheme("http", 80, PlainSocketFactory.getSocketFactory()));//http 80 端口

       registry.register(new Scheme("https", 443, sslFactory));//https 443端口

      

       PoolingClientConnectionManager cm = newPoolingClientConnectionManager(registry);//创建connectionManager

      

       cm.setDefaultMaxPerRoute(20);//对每个指定连接的服务器(指定的ip)可以创建并发20 socket进行访问

       cm.setMaxTotal(200);//创建socket的上线是200

       HttpHost localhost = new HttpHost("locahost", 80);

       cm.setMaxPerRoute(new HttpRoute(localhost), 80);//对本机80端口的socket连接上限是80

      

       HttpClient httpClient = new DefaultHttpClient(cm);//使用连接池创建连接

       HttpParams params = httpClient.getParams();

       HttpConnectionParams.setSoTimeout(params, 60*1000);//设定连接等待时间

       HttpConnectionParams.setConnectionTimeout(params,60*1000);//设定超时时间

 

       try{

           HttpGet httpGet = new HttpGet("http://m.weather.com.cn/data/101010100.html");

           HttpResponse response = httpClient.execute(httpGet);

           String result = EntityUtils.toString(response.getEntity(),Charset.forName("utf-8"));

           System.out.println(result);

       }finally{

           httpClient.getConnectionManager().shutdown();//用完了释放连接

       }

      

    }

PoolingClientConnectionManager的创建过程要比BasicClientConnectionManager复杂的多,当然,我们为了举例子,将PoolingClientConnectionManager可能涉及到的多个方面属性都列出来,可以根据需要设置或者使用默认的连接属性。首先我们创建了SchemeRegistry,之后注册了两种http访问方式http和https,创建PoolingClientConnectionManager,指定每个router最多保持20个活动的connection,这个pool最多保持200个活动的connection,对本地的访问可以保持80个活动的connection。最后创建httpClient,设置SO_TIMEOUT和CONNECTION_TIMEOUT,执行请求。在httpClient不再使用时,关闭connectionManager。

Demo2 只是个例子,说明应当如何创建一个带有缓冲池的HttpClient,在实际应用中,可以对多个访问共用一个池化的HttpClient,即提高了性能(重用connection,connection和disconnect是非常耗时的,要选路由,三次握手等),也方便了管理,有利于代码的维护。

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在使用Spring Boot中封装HttpClient时,可以使用Apache HttpClient库。以下是一个简单的封装示例: 1. 添加依赖 首先,在Maven或Gradle项目的构建文件中添加Apache HttpClient的依赖: Maven: ```xml <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.5.13</version> </dependency> ``` Gradle: ```groovy implementation 'org.apache.httpcomponents:httpclient:4.5.13' ``` 2. 创建Http请求封装类 创建一个名为HttpClientUtil的Java类,用于封装HttpClient的常用操作: ```java import org.apache.http.HttpEntity; import org.apache.http.NameValuePair; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpRequestBase; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClientBuilder; import org.apache.http.message.BasicNameValuePair; import org.apache.http.util.EntityUtils; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Map; public class HttpClientUtil { private CloseableHttpClient httpClient; public HttpClientUtil() { httpClient = HttpClientBuilder.create().build(); } public String doGet(String url) throws IOException { HttpGet request = new HttpGet(url); return executeRequest(request); } public String doPost(String url, Map<String, String> params) throws IOException { HttpPost request = new HttpPost(url); if (params != null && !params.isEmpty()) { List<NameValuePair> nameValuePairs = new ArrayList<>(); for (Map.Entry<String, String> entry : params.entrySet()) { nameValuePairs.add(new BasicNameValuePair(entry.getKey(), entry.getValue())); } request.setEntity(new UrlEncodedFormEntity(nameValuePairs)); } return executeRequest(request); } private String executeRequest(HttpRequestBase request) throws IOException { try (CloseableHttpResponse response = httpClient.execute(request)) { HttpEntity entity = response.getEntity(); if (entity != null) { return EntityUtils.toString(entity); } } return null; } } ``` 3. 使用封装类 现在,你可以在Spring Boot的任何组件中使用HttpClientUtil类进行HTTP请求。例如,在一个Controller中使用: ```java import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class MyController { private HttpClientUtil httpClientUtil; public MyController(HttpClientUtil httpClientUtil) { this.httpClientUtil = httpClientUtil; } @GetMapping("/api/request") public String makeRequest() { try { String response = httpClientUtil.doGet("https://example.com"); return response; } catch (IOException e) { e.printStackTrace(); return "Error"; } } } ``` 以上示例演示了如何封装HttpClient并在Spring Boot应用程序中使用它进行GET请求。你可以根据自己的需求,进一步扩展封装类,支持更多的HTTP方法和功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值