HttpClient 极简快速入门

更新详细的教程:https://blog.csdn.net/justry_deng/article/details/81042379

httpClient介绍

HTTP 协议可能是现在 Internet 上使用得最多、最重要的协议了,越来越多的 Java 应用程序需要直接通过 HTTP 协议来访问网络资源。虽然在 JDK 的 java net包中已经提供了访问 HTTP 协议的基本功能,但是对于大部分应用程序来说,JDK 库本身提供的功能还不够丰富和灵活。HttpClient 是 Apache Jakarta Common 下的子项目,用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包,并且它支持 HTTP 协议最新的版本和建议。HttpClient 已经应用在很多的项目中,比如 Apache Jakarta 上很著名的另外两个开源项目 Cactus 和 HTMLUnit 都使用了 HttpClient。现在HttpClient最新版本为 HttpClient 4.5 .6(2015-09-11)

导入jar包

<!--添加httpClient jar包 -->
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
        </dependency>

入门案例

//开发springCloud远程调用的源码 /是开发银行SDK的中组件/访问其他服务器数据的万能用法
public class TestHttpClient {
    
    /**
     * 步骤:
     *  1.确定目标服务器的网址
     *  2.定义请求类型    get/post/put/delete
     *  3.创建httpClient工具API对象
     *  4.发起http请求,获取服务器响应数据.
     *  5.获取服务器响应之后开始解析数据. 判断状态码信息 200/404/406/500/504
     *  6.获取数据执行业务调用.
     *  
     *  httpClient可以当做简单的爬虫使用 JSOUP/PYTHON
     * @throws IOException 
     * @throws ClientProtocolException 
     */
    @Test
    public void testGet() throws ClientProtocolException, IOException {
        String url = "https://www.baidu.com";
        HttpGet httpGet = new HttpGet(url);
        HttpClient httpClient = HttpClients.createDefault();
        HttpResponse httpResponse = httpClient.execute(httpGet);
        int status = httpResponse.getStatusLine().getStatusCode();
        if(status == 200) {
            //表示请求正确
            HttpEntity httpEntity = httpResponse.getEntity();   //获取响应数据
            String data = EntityUtils.toString(httpEntity, "UTF-8");
            System.out.println(data);
        }else {
            System.out.println("请求有误!!!!!!!!!"+status);
        }
    }
}

SpringBoot整合HttpClient

编辑properties

#最大连接数
http.maxTotal = 1000
#并发数
http.defaultMaxPerRoute = 20
#创建连接的最长时间
http.connectTimeout=5000
#从连接池中获取到连接的最长时间
http.connectionRequestTimeout=500
#数据传输的最长时间
http.socketTimeout=5000
#提交请求前测试连接是否可用
http.staleConnectionCheckEnabled=true

编辑HttpClientConfig配置类

@Configuration
@PropertySource(value="classpath:/properties/httpClient.properties")
public class HttpClientConfig {
    @Value("${http.maxTotal}")
    private Integer maxTotal;                       //最大连接数@Value("${http.defaultMaxPerRoute}")
    private Integer defaultMaxPerRoute;             //最大并发链接数@Value("${http.connectTimeout}")
    private Integer connectTimeout;                 //创建链接的最大时间@Value("${http.connectionRequestTimeout}") 
    private Integer connectionRequestTimeout;       //链接获取超时时间@Value("${http.socketTimeout}")
    private Integer socketTimeout;                  //数据传输最长时间@Value("${http.staleConnectionCheckEnabled}")
    private boolean staleConnectionCheckEnabled;    //提交时检查链接是否可用//定义httpClient链接池
    @Bean(name="httpClientConnectionManager")
    public PoolingHttpClientConnectionManager getPoolingHttpClientConnectionManager() {
        PoolingHttpClientConnectionManager manager = new PoolingHttpClientConnectionManager();
        manager.setMaxTotal(maxTotal);  //设定最大链接数
        manager.setDefaultMaxPerRoute(defaultMaxPerRoute);  //设定并发链接数
        return manager;
    }//定义HttpClient
    /**
     * 实例化连接池,设置连接池管理器。
     * 这里需要以参数形式注入上面实例化的连接池管理器
       @Qualifier 指定bean的ID为参数赋值
     */
    @Bean(name = "httpClientBuilder")
    public HttpClientBuilder getHttpClientBuilder(@Qualifier("httpClientConnectionManager")PoolingHttpClientConnectionManager httpClientConnectionManager){//HttpClientBuilder中的构造方法被protected修饰,所以这里不能直接使用new来实例化一个HttpClientBuilder,可以使用HttpClientBuilder提供的静态方法create()来获取HttpClientBuilder对象
        HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
        httpClientBuilder.setConnectionManager(httpClientConnectionManager);
        return httpClientBuilder;
    }/**
     *  注入连接池,用于获取httpClient
     * @param httpClientBuilder
     * @return
     */
    @Bean
    public CloseableHttpClient getCloseableHttpClient(@Qualifier("httpClientBuilder") HttpClientBuilder httpClientBuilder){return httpClientBuilder.build();
    }/**
     * Builder是RequestConfig的一个内部类
      * 通过RequestConfig的custom方法来获取到一个Builder对象
      * 为请求设定超时时间
     * @return
     */
    @Bean(name = "builder")
    public RequestConfig.Builder getBuilder(){
        RequestConfig.Builder builder = RequestConfig.custom();
        return builder.setConnectTimeout(connectTimeout)
                .setConnectionRequestTimeout(connectionRequestTimeout)
                .setSocketTimeout(socketTimeout)
                .setStaleConnectionCheckEnabled(staleConnectionCheckEnabled);
    }/**
     * 使用builder构建一个RequestConfig对象
     * @param builder
     * @return
     */
    @Bean
    public RequestConfig getRequestConfig(@Qualifier("builder") RequestConfig.Builder builder){
        return builder.build();
    }
}

关闭超时链接

//该类的作用  定期将超时的链接自动关闭.
@Component  //交给spring容器管理
public class HttpClientClose extends Thread{
    @Autowired
    private PoolingHttpClientConnectionManager manage;
    private volatile boolean shutdown;  
    //开关 volatitle表示多线程可变数据,一个线程修改,其他线程立即修改
    
    public HttpClientClose() {
        ///System.out.println("执行构造方法,实例化对象");
        //线程开启启动
        this.start();
    }
    
    
    @Override
    public void run() {
        try {
            //如果服务没有关闭,执行线程
            while(!shutdown) {
                synchronized (this) {
                    wait(5000);         //等待5秒
                    //System.out.println("线程开始执行,关闭超时链接");
                    //关闭超时的链接
                    PoolStats stats = manage.getTotalStats();
                    int av = stats.getAvailable();  //获取可用的线程数量
                    int pend = stats.getPending();  //获取阻塞的线程数量
                    int lea = stats.getLeased();    //获取当前正在使用的链接数量
                    int max = stats.getMax();
                    //System.out.println("max/"+max+":  av/"+av+":  pend/"+pend+":   lea/"+lea);
                    manage.closeExpiredConnections();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException();
        }super.run();
    }//关闭清理无效连接的线程
    @PreDestroy //容器关闭时执行该方法.
    public void shutdown() {
        shutdown = true;
        synchronized (this) {
            //System.out.println("关闭全部链接!!");
            notifyAll(); //全部从等待中唤醒.执行关闭操作;
        }
    }
}

编辑工具API

//如果需要使用spring容器注入对象,则本身应该交给容器管理
@Service
public class HttpClientService {
    @Autowired
    private CloseableHttpClient httpClient;
    @Autowired
    private RequestConfig requestConfig;
​
​
    /**
     * 工具API作用:
     *   为了用户简化操作而定义该工具API.
     *   目的:用户通过如下方法实现远程url调用并且获取响应结果.
     *   String result = httpClientService.doGet(url,xx,xx);
     * 
     * 编辑工具API考虑的问题:
     *   1.参数问题     (1). url请求地址     (2).Map<String,String>  (3) 设定字符集编码格式
     * 返回值问题: String类型
     * 
     * @param url
     * @param params
     * @param charset
     * @return
     */public String doGet(String url,Map<String,String> params,String charset) {//1.校验字符集编码格式
        if(StringUtils.isEmpty(charset)) {
            //如果用户没有指定字符集,则设定默认值
            charset = "UTF-8";
        }//2.封装get请求的参数.
        //2.1 get请求时没有参数      http://manage.jt.com/getXXXX
        //2.2 get请求有参数              http://manage.jt.com/getXXX?id=1&name=xxx&
        if(params != null) {
            url += "?";
            //遍历map 动态获取key=value
            for (Map.Entry<String,String> entry : params.entrySet()) {
                String key = entry.getKey();
                String value = entry.getValue();
                url += (key+"="+value+"&");
            }
            //http://manage.jt.com/getXXX?id=1&name=xxx&
            //去除多余的&符号
            url = url.substring(0, url.length()-1);
        }//3.准备请求对象
        HttpGet httpGet = new HttpGet(url);
        httpGet.setConfig(requestConfig);  //设定请求超时时间//4.利用httpClient发起请求
        try {
            HttpResponse httpResponse = httpClient.execute(httpGet);
            //获取状态码信息
            int status = 
                    httpResponse.getStatusLine().getStatusCode();
            if(status == 200) { //请求正确
                //获取返回值实体
                HttpEntity httpEntity = httpResponse.getEntity();
                String result = EntityUtils.toString(httpEntity,charset);
                return result;
            }} catch (IOException e) {
​
            e.printStackTrace();
            thORw new RuntimeException(e);
        }return null;
    }
​
​
    //方法的重载      满足不同的用户需求
    public String doGet(String url) {return doGet(url, null, null);
    }public String doGet(String url,Map<String,String> params) {return doGet(url, params, null);
    }
​
​
​
    //实现httpClient POST提交
    public String doPost(String url,Map<String,String> params,String charset){
        String result = null;//1.定义请求类型
        HttpPost post = new HttpPost(url);
        post.setConfig(requestConfig);      //定义超时时间//2.判断字符集是否为null
        if(StringUtils.isEmpty(charset)){
​
            charset = "UTF-8";
        }//3.判断用户是否传递参数
        if(params !=null){
            //3.2准备List集合信息
            List<NameValuePair> parameters = 
                    new ArrayList<>();//3.3将数据封装到List集合中
            for (Map.Entry<String,String> entry : params.entrySet()) {
​
                parameters.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
            }//3.1模拟表单提交
            try {
                UrlEncodedFormEntity formEntity = 
                        new UrlEncodedFormEntity(parameters,charset); //采用u8编码//3.4将实体对象封装到请求对象中
                post.setEntity(formEntity);
            } catch (UnsupportedEncodingException e) {
​
                e.printStackTrace();
            }
        }//4.发送请求
        try {
            CloseableHttpResponse response = 
                    httpClient.execute(post);//4.1判断返回值状态
            if(response.getStatusLine().getStatusCode() == 200) {//4.2表示请求成功
                result = EntityUtils.toString(response.getEntity(),charset);
            }else{
                System.out.println("获取状态码信息:"+response.getStatusLine().getStatusCode());
                thORw new RuntimeException();
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }return result;
    }
​
​
​
    public String doPost(String url){return doPost(url, null, null);
    }public String doPost(String url,Map<String,String> params){return doPost(url, params, null);
    }public String doPost(String url,String charset){return doPost(url, null, charset);
    }
}

本文内容均来自江哥笔记!!!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

光头小小强007

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值