Java4Android之httpclient学习与应用

Java HTTP客户端深度对比:OkHttp、HttpClient与WebClient选型指南 HTTP客户端是现代软件开发中处理网络通信的核心组件,它负责在应用与服务端之间传输数据。其工作原理基于HTTP协议,通过建立连接、发送请求和接收响应来完成数据交换。在技术价值上,一个优秀的HTTP客户端能显著提升应用性能、降低资源消耗并增强系统稳定性。在实际应用场景中,无论是微服务间的通信、移动端数据拉取还是API调用,都离不开高效的HTTP客户端支持。本文聚焦于Java生态中三个主流解决方案:OkHttp以其强大的连接池管理和拦截器机制著称;JDK 11+内置的HttpClient提供了标准化现代API; 阅读详情

在Java开发中,不可避免的需要和http打交道。而无论我司的迅雷动漫还是我主导的“搜芽”android客户端开发,都需要使用到http和服务器打交道。。虽然Java也提供了http的接口,但据我了解,更多的公司都是使用Apache的httpclient来进行开发,不仅因为它灵活强大,而且便捷。

今天,我们学习httpclient的基础知识。

关于Http的基础,在此就不再复习了。建议大家去看一本权威制作《HTTP权威指南》,加个略贵,109元人民币,不过,我买了,因为经典的书,还是多备一下,我也没怎么看,但遇到问题就翻即可。


闲话少说,切入正题。

我们发出一个http的请求,在httpclient中一般如下流程模式:

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

代码示例如下:

CloseableHttpClient httpclient = HttpClients.createDefault();
HttpGet httpget = new HttpGet("http://localhost/");
CloseableHttpResponse response = httpclient.execute(httpget);
try {
<...>
} finally {
response.close();
}

请求:

HttpClient支持所有的HTTP/1.1的所有命令,包含:GET,HEAD,POST,PUT,DELETE,TRACE和OPTIONS。而且都有单独对应的类:HttpGet,HttpHead,....等等。

请求URI是统一资源标识符,标识了你所要请求的资源。它一般包含protocol scheme , host name, optional port, resource path,optional query ,optional fragment这些信息。如:

HttpGet httpget = new HttpGet(
"http://www.google.com/search?hl=en&q=httpclient&btnG=Google+Search&aq=f&oq=");
构造上述URI一个更为好的方法是使用URIBuilder。具体如下:

URI uri = new URIBuilder()
.setScheme("http")
.setHost("www.google.com")
.setPath("/search")
.setParameter("q", "httpclient")
.setParameter("btnG", "Google Search")
.setParameter("aq", "f")
.setParameter("oq", "")
.build();
HttpGet httpget = new HttpGet(uri);


回复:

回复(response)是服务器对客户端的回复。httpclient中的回复是HttpResponse.

HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1,
HttpStatus.SC_OK, "OK");
System.out.println(response.getProtocolVersion());
System.out.println(response.getStatusLine().getStatusCode());
System.out.println(response.getStatusLine().getReasonPhrase());
System.out.println(response.getStatusLine().toString());
输出:
HTTP/1.1
200
OK
HTTP/1.1 200 OK

消息头部:

如果大家熟悉HTTP包的话,就知道一个HTTP报文是由三个部分组成的:对报文进行描述的起始行(start line),包含属性的首部块(header),以及可选的,包含数据的主体部分(body)。

httpclient的一个关于头部的示例:

HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1,
HttpStatus.SC_OK, "OK");
response.addHeader("Set-Cookie",
"c1=a; path=/; domain=localhost");
response.addHeader("Set-Cookie",
"c2=b; path=\"/\", c3=c; domain=\"localhost\"");
Header h1 = response.getFirstHeader("Set-Cookie");
System.out.println(h1);
Header h2 = response.getLastHeader("Set-Cookie");
System.out.println(h2);
Header[] hs = response.getHeaders("Set-Cookie");
System.out.println(hs.length);

其输出结果:

Set-Cookie: c1=a; path=/; domain=localhost
Set-Cookie: c2=b; path="/", c3=c; domain="localhost"
2

HTTP 实体(entity):

在httpclient中存在三种实体,streamed,self-contained和wrapping。它们的区别在我们用到的时候再区分,一般而言,流对象适合接收流数据,self-contained自包含适合那些可重复读取的场景。wrapping是对已有实体的一个包装。
下面是一个使用实体的例子:
CloseableHttpClient httpclient = HttpClients.createDefault();
HttpGet httpget = new HttpGet("http://localhost/");
CloseableHttpResponse response = httpclient.execute(httpget);
try {
HttpEntity entity = response.getEntity();
if (entity != null) {
InputStream instream = entity.getContent();
try {
// do something useful
} finally {
instream.close();
}
}
} finally {
response.close();
}

对实体的使用:
CloseableHttpClient httpclient = HttpClients.createDefault();
HttpGet httpget = new HttpGet("http://localhost/");
CloseableHttpResponse response = httpclient.execute(httpget);
try {
HttpEntity entity = response.getEntity();
if (entity != null) {
long len = entity.getContentLength();
if (len != -1 && len < 2048) {
System.out.println(EntityUtils.toString(entity));
} else {
// Stream content out
}
}
} finally {
response.close();
}

那么,如何产生一个实体呢:
实体有分很多种类,所以httpclient也提供了几个产生实体的类,分别产生对应的实体。StringEntity,ByteArrayEntity,InputStreamEntity和FileEntity,它们分别产生string, byte array, input stream ,file。一个fileEntity的示例如下:
File file = new File("somefile.txt");
FileEntity entity = new FileEntity(file,
ContentType.create("text/plain", "UTF-8"));
HttpPost httppost = new HttpP

表单:
httpclient也提供了类似与http表单的功能,比如用户登入页面,需要用户名和密码。
List<NameValuePair> formparams = new ArrayList<NameValuePair>();
formparams.add(new BasicNameValuePair("param1", "value1"));
formparams.add(new BasicNameValuePair("param2", "value2"));
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(formparams, Consts.UTF_8);
HttpPost httppost = new HttpPost("http://localhost/handler.do");
httppost.setEntity(entity);
会产生如下效果:
param1=value1&m2=value2


在最后,我给出我们对httpclient的GET和POST 的方法的一个封装,这里里面的代码会将我们前面讲到的元素都涉及到。
 private InputStream httpGet(String url, String cookie) {
        HttpGet httpGet = new HttpGet(url);
        httpGet.setHeader("Accept-Encoding", "gzip,deflate");
        if (!(TextUtils.isEmpty(cookie))) {
            httpGet.setHeader("Cookie", cookie);
        }
        return httpDo(httpGet, url, null);
    }

    private InputStream httpPost(String url, Map<String, String> headers,
            Map<String, Object> params) {
        HttpPost post = new HttpPost(url);

        HttpEntity entity = null;
        Object value = params.get(POST_ENTITY);
        if (value instanceof HttpEntity) {
            entity = (HttpEntity) value;
        } else {
            List<NameValuePair> pairs = new ArrayList<NameValuePair>();
            for (Map.Entry<String, Object> e : params.entrySet()) {
                value = e.getValue();
                if (value != null) {
                    LOG.debug("param=" + e.getKey() + ":" + value.toString());
                    pairs.add(new BasicNameValuePair(e.getKey(), value
                            .toString()));
                }
            }
            try {
                entity = new UrlEncodedFormEntity(pairs, "UTF-8");
            } catch (UnsupportedEncodingException e1) {
                LOG.warn("UnsupportedEncodingException err={}", e1.toString());
            }
        }

        if (headers != null && !headers.containsKey("Content-Type")) {
            headers.put("Content-Type",
                    "application/x-www-form-urlencoded;charset=UTF-8");
        }
        post.setEntity(entity);

        return httpDo(post, url, headers);
    }

    private InputStream httpDo(HttpUriRequest hr, String url,
            Map<String, String> headers) {
        InputStream in = null;
        if (headers != null) {
            for (String name : headers.keySet()) {
                hr.addHeader(name, headers.get(name));
            }
        }

        DefaultHttpClient client = getClient();
        HttpResponse response;
        try {
            response = client.execute(hr);

            int statusCode = response.getStatusLine().getStatusCode();
            LOG.debug("this={}, response code={}", this, statusCode);

            if (statusCode == HttpStatus.SC_OK) {
                HttpEntity entity = response.getEntity();
                if (null != entity) {
                    Header header = entity.getContentEncoding();
                    if (header != null && header.getValue().equals("gzip")) {
                        in = new GZIPInputStream(entity.getContent());
                    } else {
                        in = entity.getContent();
                    }
                }
            } else {
                LOG.warn("Request HTTP resource failed. StatusCode={} Url={}", statusCode, url);
            }
        } catch (IOException e) {
            LOG.warn("Request HTTP resource failed. {}, err={}", this, e.toString());
        } catch (IllegalStateException e) {
            LOG.warn("Request HTTP resource failed. url={} err={}", url, e.toString());
        }

        return in;
    }

    private static DefaultHttpClient getClient() {
        HttpParams httpParams = new BasicHttpParams();
        HttpConnectionParams.setConnectionTimeout(httpParams, CONNECTION_TIMEOUT);
        HttpConnectionParams.setSoTimeout(httpParams, SO_TIMEOUT);
        // http://stackoverflow.com/questions/5358014/android-httpclient-oom-on-4g-lte-htc-thunderbolt
        HttpConnectionParams.setSocketBufferSize(httpParams, 8192);

        return new DefaultHttpClient(httpParams);
    }

时间有限,今天到此为止。












Apache Commons HttpClient 3.1安卓开发实战详解 Apache HttpClient 3.1 是 Java 平台早期最广泛使用的 HTTP 客户端库之一,作为 Jakarta Commons 项目的重要组成部分,它为开发者提供了简洁、灵活且可扩展的编程接口,用于实现 HTTP/1.1 协议的客户端通信。该版本发布于2007年,正值 Web 服务快速发展的时代,其设计目标是替代 JDK 原生 URLConnection 的复杂性和局限性,提供更高级别的抽象和更强的控制能力。 阅读详情

相关推荐

SPSS中的数据分析—信度效度检验【1】

前一段时间跟大家分享了好几篇关于EXCEL方面的数据分析知识,不知道大家都掌握得怎么样了。今天咱们换个口味,给大家讲一下关于SPSS中的数据分析——信度效度检验。 现阶段正处在毕业季阶段,很多同学可能都正在忙着去弄自己的论文和答辩(不知道大家在翟天临上热搜这个事情上有没有做出过一定贡献),很多时候我们在写论文答辩甚至于其他课题研究的时候都会选择用问卷这种形式来收集数据。最后我们只需要针对问卷所取...

小白数据营的博客 6万+

android http设置body,HTTP body post in android

I am new to android development. In my application I have to use HTTP body post. But I'm getting an error.Here is my code:HttpClient httpclient = new DefaultHttpClient();HttpPost httppost = new HttpPo...

weixin_39990558的博客 429

《软件工程——实践者的研究方法》重难点复习笔记(第八章——理解需求)

8项需求工程任务 inception 开始 8.1.1 identify stakeholders 定义:从软件开发中收益 例如:市场人员、销售经理、顾客、顾问、维护团队等(P139) 8.1.2 这个阶段的问题是context-free的。有三套(P140) 8.1.3 提到NFR(nonfunctional requirement)和QFD(quality

whooiif的博客 1815

java httpclient posbody,Android平台下轻量级http网络传输库

AsyncHttpHelp是一个android平台下基于httpclient开发的HTTP网络请求工具。优点功能齐全,提供常用的http网络访问接口。轻量级,无任何第三方库依赖,库大小为90K左右。定制化,自定义json解析库,支持请求参数,返回内容预处理。易用性,简单易用,只需几行代码即可完成请求,可随意设置cookie、http头部等信息。功能1、普通get请求2、普通post请求3、Form...

weixin_35733151的博客 198

关于三维全波电磁场仿真软件CST的安装和问题解决

百度网盘链接:https://pan.baidu.com/s/1RgWr8Qau1EzSOlh29SewFQ提取码:fzza这里是2023版本的CST,需要其他版本的uu们可以去官网或者其他人的网盘下载。

weixin_60728441的博客 3611

开源ISP介绍(1)——开源ISP的Vivado框架搭建

ZYNQ视频图像处理系统,ISP图像处理硬件实现

路漫漫其修远兮,吾将上下而求索 3288

Java4Android之HttpClient入门使用代码集

本文将从代码的角度去引导如何使用httpclient的各个功能和特性。 第一个程序 import org.apache.commons.httpclient.*; import org.apache.commons.httpclient.methods.*; import org.apache.commons.httpclient.params.HttpMethodParams; impor

MiniMicall的专栏 1900

OpenHarmony之Histreamer引擎深度解析:pipeline_core架构如何全面取代GStreamer,一统音视频播放与录制

Histreamer是OpenHarmony多媒体框架的核心媒体引擎,采用架构设计。一个轻量级的媒体引擎组件,提供播放、录制等场景的媒体数据流水线处理。1.播放场景分为如下几个节点:数据源读取、解封装、解码、输出;2.录制场景分为如下几个节点:数据源读取、编码、封装、输出。该引擎从OH5.0开始取代了原有的媒体引擎gstreamer(部分文档还保留较老架构的讲解),提供统一的音视频播放、录制、元数据解析等能力。

m0_67505153的博客 333

android httpclient基本用法

android  httpclient常用的post get delete put 方法简单使用 传值方式:文本键值对格式 和 json格式 /** * 通过Put方式发送请求 更新采集器信息 * @param url URL地址 * @param params 参数 * @return * @throws Exception */ p

H291850336的专栏 3269

目标检测YOLO实战应用案例100讲-基于YOLOv7的番茄采摘机械手场景感知及试验(下)

根据软件系统的设计需求,制定系统的可行性方案分析,编写系统的相关程序和 调试运行环境,对系统进行测试,以实现对番茄数据的采集及监测。登陆界面登陆后,进入选择界面,菜单包括了对番茄种植棚室的固定相机数据的监测、 对番茄采摘机械手的双目相机采集的番茄的静态、动态数据的获取、对番茄静态、动态数 据处理的功能菜单等选项。与利用人工去进行对于番茄果实的识别和数目的统计相比,番茄视觉系统自动记录番 茄数量以及红色已经成熟的番茄、青色未成熟番茄的数量,减轻人工记录的工作量,减少 人工记录的误差,从经济方面是可行的。

qq_36130719的博客 812

Python爬虫模拟登录京东并抓取商品数据

京东是一个拥有海量商品数据的电子商务平台。作为爬虫开发者,能够抓取这些数据将为我们提供很多机会进行数据分析、价格预测、市场调研等工作。然而,京东的反爬虫机制非常强大,包括但不限于验证码、动态加载页面、IP封禁等。因此,想要通过Python爬虫抓取京东的数据并不容易。在本文中,我们将从分析京东的登录机制开始,逐步介绍如何使用Python中的各种工具,如。

2201_76125261的博客 1828

Android 使用 HttpClient 进行网络通信,包括Get方式和Post方式

要使用HttpClient,需要了解一些类: 1、ClientConnectionManager接口:该接口是客户端连接管理器接口,主要提供以下几个抽象方法: ClientConnectionManager(关闭所有无效超时的连接)、closeIdleConnection(关闭空闲的连接)、releaseConnection(释放一个连接)、requestConnection(请求一个新的连接

1万+

达梦数据库修改最大连接数

达梦数据库的最大连接数推荐配置与服务器内存有关。不应设置得过大,否则容易导致出现OOM。文件中整型的参数值。DSC环境下,除了特殊参数以外,其他参数值会在OK节点上同步。返回值:当前DM.INI文件中对应的参数值。功能说明:返回DM.INI文件中。:DM.INI文件中的参数名。

Sebastien23的博客 3336

Apache Httpclient4.5学习笔记

很早之前写过一个java爬虫,用来抓某网站妹子图片的,用到了httpclient包,但是没有认真理解方法,只是为了实现功能而拼凑了一个东西出来,当然也还为了好玩。 现在不一样了,已经决定了不考研,而又处于大三这个开始有找工作的压力的情况下,自然要开始学习磨炼自己的技术。再加上学习安卓网络编程正好用到了httpclient包,于是就下载了官方手册仔细的学了一学,现在在这里写下来我对第一部分(Pos

ztgreenleaves的博客 1882

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

Android端与Java端的数据交互

Android从第三方项目获取数据通常使用这两种方式   1,xml格式的数据交互(对xml进行解析获取数据)   2,json格式的数据交互(对json格式数据进行解析,使用HttpClient技术访问后台代码) HttpClient的使用步骤 3. HttpClient的使用步骤   3.1 创建HttpClient对象       HttpClient httpClient = n...

Giraffe_it的博客 4204

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

安卓开发-HttpClient使用

http://blog.youkuaiyun.com/imzoer/article/details/9447985 http://blog.youkuaiyun.com/imzoer/article/details/9447985 http://blog.youkuaiyun.com/imzoer/article/details/9447985 安卓开发-HttpClie

981

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

在Android中使用HttpClient 4.3.x出现NoSuchFieldError的问题

升级了 HttpClient 前几天看到Apache新发布了 HttpClient 4.3.5,一时手残,将我写的开源项目nForumSDK中的 HttpClient 升级了。 在纯Java的环境下测试了一下,没发现什么问题,新的包还挺好用的,于是就发布了。 过了两天,有人给我发反馈,说在Android应用上测试的时候报错: java.lang.NoSuchFieldError:org.a

dss886的专栏 1167

Android HTTP请求用HttpUrlConnection与HttpClient比较

在安卓和JAVA应用开发中需要访问网络,少不了要提交HTTP请求,而基本上目前有两个实现方式:HttpUrlConnection(即URL.openConnection)和HttpClient。     网上不少人都认为HttpClient更好,理由是功能更强,BUG更少,更容易控制细节。但我个人认为普通JAVA人员可选用HttpClient,安卓开发人员则应该使用HttpUrlConnec

zhangcanyan的博客 3002

HttpClient、OKhttp、RestTemplate对比

一、三者的对比 HttpClient:代码复杂,还得操心资源回收等。代码很复杂,冗余代码多,不建议直接使用。 RestTemplate: 是 Spring 提供的用于访问Rest服务的客户端, RestTemplate 提供了多种便捷访问远程Http服务的方法,能够大大提高客户端的编写效率。 okhttp:OkHttp是一个高效的HTTP客户端,允许所有同一个主机地址的请求共享同一个socket连接;连接池减少请求延时;透明的GZIP压缩减少响应数据的大小;缓存响应内容,避免一些完全重复的请求 二、Ht

cristianoxm的博客 1万+

安卓Http编程之HttpClient

android培训、java培训、期待与您交流! Apache提供HttpClient,它对java.net中的类做了封装和抽象,更适合在Android上开发应用。 HttpClient应用开发几个类: 1. ClientConnectionManager是客户端连接管理器的接口, 提供以下几个抽象方法: closeIdleConnections, 关闭空闲的连接 releas

piaoyi493279486的博客 538

关于安卓HTTP请求用HttpUrlConnection还是HttpClient好

安卓和JAVA应用开发少不了要提交HTTP请求,而基本上目前有两个实现方式:HttpUrlConnection(即URL.openConnection)和HttpClient。 网上不少人都认为HttpClient更好,理由是功能更强,BUG更少,更容易控制细节。但我个人认为普通JAVA人员可选用HttpClient,安卓开发人员则应该使用HttpUrlConnection,理由如下:

cocoooooa的专栏 879

android中HttpUrlConnection与HttpClient区别

安卓和JAVA应用开发少不了要提交HTTP请求,而基本上目前有两个实现方式:HttpUrlConnection(即URL.openConnection)和HttpClient。 网上不少人都认为HttpClient更好,理由是功能更强,BUG更少,更容易控制细节。但我个人认为普通JAVA人员可选用HttpClient,安卓开发人员则应该使用HttpUrlConnection,理由如下:

crissJs的专栏 566

android 登录Javaeye(使用HttpURLConnection和HttpClient)

之前在网上看过好多人用java写登录网站,这次正好学习android,自己写实习一个,就拿经常登录的javaeye(现在叫iteye,已经是csdn的了)试一下。 先来分析javaeye登录界面 查看源文件 账号

dellheng的专栏 2620

Android httpclient、json

webservice-&gt;xml jackson-&gt;json 从第三方项目中拿数据通常有两种方式(根据数据交互的格式来定) xml-&gt;webservice/httpClient json-&gt;httpClient java java java android java ios java 微信 jackson 1.1 Java-&gt;Json 1.1.1 ObjectMap...

KidShmily的博客 331

HttpClient for Android:为Android设备优化的HTTP客户端库

HttpClient for Android:为Android设备优化的HTTP客户端库 HttpClient for Android 是一个开源项目,致力于为Android平台提供高性能、易于使用的HTTP客户端库。该项目基于Apache HttpClient,并针对Android设备进行了优化。主要使用的编程语言是Java。 项目基础介绍 HttpClient for Android 项目旨在...

gitblog_00963的博客 430
上一篇: Java4Android之Gson
下一篇: Java4Android之HttpClient入门使用代码集
minimicall
博客等级 码龄18年 407粉丝 174原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值