HttpClient 解决通讯问题

为什么会存在通讯问题

在单体应用程序开发中,常把前端模块、后台模块、系统管理模块、数据库等统一部署在一个服务器上。先说一下这样部署的缺点:

  • 多个服务部署在一台服务器上系统承载压力过大,容易造成宕机。
  • 数据后台数据管理不安全,通过IP地址,后台管理页面容器被非管理人员打开。
  • 项目更新时,部署需要将所有服务停止,造成业务上的损失。

所以越来越多的服务,开始往分布式系统转变。一台服务器,部署一个服务。增加了数据安全,并发数量,以及部署的便捷。
但是多个服务器之间存在业务调用,又是如何调用的呢?
下图展示了一个业务的分布式部署与模块通讯架构:
在这里插入图片描述

Apache HttpClient 简介

HttpClient 是 Apache Jakarta Common 下的子项目,用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包,并且它支持 HTTP 协议最新的版本和建议。HttpClient 已经应用在很多的项目中,比如 Apache Jakarta 上很著名的另外两个开源项目 Cactus 和 HTMLUnit 都使用了 HttpClient。

HttpClient 相比传统 JDK 自带的 URLConnection,增加了易用性和灵活性,它不仅是客户端发送 HTTP 请求变得容易,而且也方便了开发人员测试接口(基于 HTTP 协议的),即提高了开发的效率,也方便提高代码的健壮性。因此熟练掌握 HttpClient 是很重要的必修内容,掌握 HttpClient 后,相信对于 HTTP 协议的了解会更加深入。

Apache HttpClient特性

  • 基于标准、纯净的Java语言。实现了HTTP1.0和HTTP1.1
  • 以可扩展的面向对象的结构实现了 HTTP 全部的方法(GET, POST, PUT, DELETE, HEAD, OPTIONS, and TRACE)。
  • 支持HTPPS协议。
  • 通过HTPP代理建立透明的连接。
  • 利用CONNECT方法通过HTTP代理建立隧道的HTTPS连接。
  • Basic, Digest, NTLMv1, NTLMv2, NTLM2 Session, SNPNEGO/Kerberos 认证方案。
  • 插件式的自定义认证方案。
  • 便携可靠的套接字(socket)工厂使它更容易的使用第三方解决方案。
  • 连接管理器支持多线程应用。支持设置最大连接数,同时支持设置每个主机的最大连接数,发现并关闭过期的连接。
  • 自动处理 Set-Cookie 中的 Cookie。
  • 插件式的自定义 Cookie 策略。
  • Request 的输出流可以避免流中内容直接缓冲到 Socket 服务器。
  • Response 的输入流可以有效的从 Socket 服务器直接读取相应内容。
  • 在 HTTP 1.0 和 HTTP 1.1 中利用 KeepAlive 保持持久连接。 长连接
  • 直接获取服务器发送的 response code 和 headers。
  • 设置连接超时的能力。
  • 实验性的支持 HTTP 1.1 response caching。
  • 源代码基于 Apache License 可免费获取。

Apache HttpClient 使用流程

使用 HttpClient 发送请求、接收响应很简单,一般需要如下几步即可。

  • 创建HttpClient对象。
  • 创建请求方法的实例,并指定请求URL。如果需要发送GET请求,创建HttpGet对象;如果需要发POST请求,创建HttpPost对象。
  • 如果需要发送请求参数,可调用HttpGet、HttpPost的共同方法setParams(HttpParams params) 方法来添加请求参数;对于HttpPost对象而言,也可调用*setEntity(HtppEntity entiry)*方法来设置请求参数。
  • 调用HttpClient对象的 *execute(HttpUriRequest request)*发送请求,该方法返回一个HttpResponse。
  • 调用HttpResponse的getAllHeaders( )、getHeader(String name)等方法可以获取服务器的响应头;调用HttpResponse的getEntity( )方法可以获取HttpEntity对象,该对象包装了服务器的响应内容。程序可通过该对象获取服务器的响应内容。
  • 释放连接。无论执行方法是否成功,都必须释放连接。

Apache HttpClient使用实例

创建Java Maven 项目
POM
pom.xml 配置如下:

<!-- Apache Http Begin -->
<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>4.5.5</version>
</dependency>
<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>fluent-hc</artifactId>
    <version>4.5.5</version>
</dependency>
<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpmime</artifactId>
    <version>4.5.5</version>
</dependency>
<!-- Apache Http End -->

主要增加了 org.apache.httpcomponents:httpclient、org.apache.httpcomponents:fluent-hc、org.apache.httpcomponents:httpmime 三个依赖

创建 HttpGet 请求

案例代码如下:

 public static void get() {
        //创建HtppClient 客户端 (打开浏览器)
        CloseableHttpClient httpClient = HttpClients.createDefault();


        //创建Get请求,输入URL
        HttpGet httpGet = new HttpGet("http://localhost:8080/SpringBootMybatis/query");
        //设置Cookie
        httpGet.setHeader("Cookie", "_ga=GA1.1.1871032103.1560703596; Idea-d1852ee0=3b5cce65-fefb-4a15-94cf-b4a7b31f2380; rdt_uuid=4e851cb2-10bb-4884-9415-2c3a2b5d3407");
        //设置长连接
        httpGet.setHeader("Connection", "keep-alive");
        //设置访问浏览器版本
        httpGet.setHeader("User-Agent","Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.122 Mobile Safari/537.36");


        //创建响应对象
        CloseableHttpResponse httpResponse = null;
        try {
            //发送请求 回车执行
            httpResponse = httpClient.execute(httpGet);
            //解析实体
            HttpEntity httpEntity = httpResponse.getEntity();
            //输出请求结果
            System.out.println(EntityUtils.toString(httpEntity));

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //关闭连接 必须
            if (httpResponse != null) {
                try {
                    httpResponse.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (httpClient != null) {
                try {
                    httpClient.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

控制台输出如下:

[{"id":1,"username":"zhansan ","password":"123456","name":"James"},{"id":2,"username":"lisi","password":"123456","name":"List"},{"id":3,"username":"wangwu","password":"123456","name":"Wang"}]

创建HttpPost请求

案例如下:

public static void post() {
        //创建HtppClient 客户端 (打开浏览器)
        CloseableHttpClient httpClient = HttpClients.createDefault();
        // 创建 HttpPost 请求
        HttpPost httpPost = new HttpPost("http://localhost:8080/content/page");
        // 设置长连接
        httpPost.setHeader("Connection", "keep-alive");
        // 设置代理(模拟浏览器版本)
        httpPost.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36");
        // 设置 Cookie
        httpPost.setHeader("Cookie", "UM_distinctid=16442706a09352-0376059833914f-3c604504-1fa400-16442706a0b345; CNZZDATA1262458286=1603637673-1530123020-%7C1530123020; JSESSIONID=805587506F1594AE02DC45845A7216A4");
        // 创建 HttpPost 参数
        List<BasicNameValuePair> params = new ArrayList<BasicNameValuePair>();
        params.add(new BasicNameValuePair("draw", "1"));
        params.add(new BasicNameValuePair("start", "0"));
        params.add(new BasicNameValuePair("length", "10"));

        CloseableHttpResponse httpResponse = null;
        try {
            // 设置 HttpPost 参数
            httpPost.setEntity(new UrlEncodedFormEntity(params, "UTF-8"));
            httpResponse = httpClient.execute(httpPost);
            HttpEntity httpEntity = httpResponse.getEntity();
            // 输出请求结果
            System.out.println(EntityUtils.toString(httpEntity));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 无论如何必须关闭连接
        finally {
            try {
                if (httpResponse != null) {
                    httpResponse.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (httpClient != null) {
                    httpClient.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

控制台输出如下:

{"draw":1,"recordsTotal":1,"recordsFiltered":1,"data":[{"id":33,"created":1530542074000,"updated":1530542074000,"title":"ad1","subTitle":"ad1","titleDesc":"ad1","url":"https://sale.jd.com/act/XkCzhoisOMSW.html","pic":"https://m.360buyimg.com/babel/jfs/t20164/187/1771326168/92964/b42fade7/5b359ab2N93be3a65.jpg","pic2":"","content":"<p><br></p>","tbContentCategory":{"id":89,"created":null,"updated":null,"parent":null,"isParent":null,"name":"幻灯片","status":null,"sortOrder":null}}],"error":null}

以上就是HttpClient的基本用法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

真香号

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

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

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

打赏作者

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

抵扣说明:

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

余额充值