转自:https://www.jianshu.com/p/375be5929bed

一、HttpClient使用详解与实战一:普通的GET和POST请求

简介

HttpClient是Apache Jakarta Common下的子项目,用来提供高效的、最新的、功能丰富的支持HTTP协议的客户端编程工具包,并且它支持HTTP协议最新的版本和建议。
HttpClient最新版本是HttpClient 4.5.3 (GA)。
官方下载:http://hc.apache.org/downloads.cgi

主要特性

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

一般使用步骤

使用HttpClient发送请求、接收响应,一般需要以下步骤。
HttpGet请求响应的一般步骤:
1). 创建HttpClient对象,可以使用HttpClients.createDefault()
2). 如果是无参数的GET请求,则直接使用构造方法HttpGet(String url)创建HttpGet对象即可;
如果是带参数GET请求,则可以先使用URIBuilder(String url)创建对象,再调用addParameter(String param, String value),或setParameter(String param, String value)来设置请求参数,并调用build()方法构建一个URI对象。只有构造方法HttpGet(URI uri)来创建HttpGet对象。
3). 创建HttpResponse,调用HttpClient对象的execute(HttpUriRequest request)发送请求,该方法返回一个HttpResponse。调用HttpResponsegetAllHeaders()、getHeaders(String name)等方法可获取服务器的响应头;调用HttpResponsegetEntity()方法可获取HttpEntity对象,该对象包装了服务器的响应内容。程序可通过该对象获取服务器的响应内容。通过调用getStatusLine().getStatusCode()可以获取响应状态码。
4). 释放连接。

HttpPost请求响应的一般步骤:
1). 创建HttpClient对象,可以使用HttpClients.createDefault()
2). 如果是无参数的GET请求,则直接使用构造方法HttpPost(String url)创建HttpPost对象即可;
如果是带参数POST请求,先构建HttpEntity对象并设置请求参数,然后调用setEntity(HttpEntity entity)创建HttpPost对象。
3). 创建HttpResponse,调用HttpClient对象的execute(HttpUriRequest request)发送请求,该方法返回一个HttpResponse。调用HttpResponsegetAllHeaders()、getHeaders(String name)等方法可获取服务器的响应头;调用HttpResponsegetEntity()方法可获取HttpEntity对象,该对象包装了服务器的响应内容。程序可通过该对象获取服务器的响应内容。通过调用getStatusLine().getStatusCode()可以获取响应状态码。
4). 释放连接。

实例代码实战

构建一个Maven项目,引入如下依赖

 <dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.3.5</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.7</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-io</artifactId>
<version>1.3.2</version>
</dependency>

实例1:普通的无参数GET请求

打开一个url,抓取响应结果输出成html文件

 /**
*普通的GET请求
*/
public class DoGET {
public static void main(String[] args) throws Exception {
// 创建Httpclient对象
CloseableHttpClient httpclient = HttpClients.createDefault();
// 创建http GET请求
HttpGet httpGet = new HttpGet("http://www.baidu.com");
CloseableHttpResponse response = null;
try {
// 执行请求
response = httpclient.execute(httpGet);
// 判断返回状态是否为200
if (response.getStatusLine().getStatusCode() == 200) {
//请求体内容
String content = EntityUtils.toString(response.getEntity(), "UTF-8");
//内容写入文件
FileUtils.writeStringToFile(new File("E:\\devtest\\baidu.html"), content, "UTF-8");
System.out.println("内容长度:"+content.length());
}
} finally {
if (response != null) {
response.close();
}
//相当于关闭浏览器
httpclient.close();
}
}
}

实例2:执行带参数的GET请求

模拟使用百度搜索关键字"java",并保存搜索结果为html文件

 import java.io.File;
import java.net.URI;
import org.apache.commons.io.FileUtils;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
/**
* 带参数的GET请求
* 两种方式:
* 1.直接将参数拼接到url后面 如:?wd=java
* 2.使用URI的方法设置参数 setParameter("wd", "java")
*/
public class DoGETParam {
public static void main(String[] args) throws Exception {
// 创建Httpclient对象
CloseableHttpClient httpclient = HttpClients.createDefault();
// 定义请求的参数
URI uri = new URIBuilder("http://www.baidu.com/s").setParameter("wd", "java").build();
// 创建http GET请求
HttpGet httpGet = new HttpGet(uri);
//response 对象
CloseableHttpResponse response = null;
try {
// 执行http get请求
response = httpclient.execute(httpGet);
// 判断返回状态是否为200
if (response.getStatusLine().getStatusCode() == 200) {
String content = EntityUtils.toString(response.getEntity(), "UTF-8");
//内容写入文件
FileUtils.writeStringToFile(new File("E:\\devtest\\baidu-param.html"), content, "UTF-8");
System.out.println("内容长度:"+content.length());
}
} finally {
if (response != null) {
response.close();
}
httpclient.close();
}
}
}

实例3:执行普通的POST请求

无参数的POST请求,并设置Header来伪装浏览器请求

 import org.apache.commons.io.FileUtils;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils; import java.io.File; /**
* 常规post请求
* 可以设置Header来伪装浏览器请求
*/
public class DoPOST {
public static void main(String[] args) throws Exception {
// 创建Httpclient对象
CloseableHttpClient httpclient = HttpClients.createDefault();
// 创建http POST请求
HttpPost httpPost = new HttpPost("http://www.oschina.net/");
//伪装浏览器请求
httpPost.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36");
CloseableHttpResponse response = null;
try {
// 执行请求
response = httpclient.execute(httpPost);
// 判断返回状态是否为200
if (response.getStatusLine().getStatusCode() == 200) {
String content = EntityUtils.toString(response.getEntity(), "UTF-8");
//内容写入文件
FileUtils.writeStringToFile(new File("E:\\devtest\\oschina.html"), content, "UTF-8");
System.out.println("内容长度:"+content.length());
}
} finally {
if (response != null) {
response.close();
}
httpclient.close();
}
}
}

实例4:执行带参数的POST请求

模拟开源中国检索java,并伪装浏览器请求,输出响应结果为html文件

 
检索java
 import java.io.File;
import java.util.ArrayList;
import java.util.List; import org.apache.commons.io.FileUtils;
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.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils; /**
* 带有参数的Post请求
* NameValuePair
*/
public class DoPOSTParam {
public static void main(String[] args) throws Exception {
// 创建Httpclient对象
CloseableHttpClient httpclient = HttpClients.createDefault();
// 创建http POST请求
HttpPost httpPost = new HttpPost("http://www.oschina.net/search");
// 设置2个post参数,一个是scope、一个是q
List<NameValuePair> parameters = new ArrayList<NameValuePair>(0);
parameters.add(new BasicNameValuePair("scope", "project"));
parameters.add(new BasicNameValuePair("q", "java"));
// 构造一个form表单式的实体
UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(parameters);
// 将请求实体设置到httpPost对象中
httpPost.setEntity(formEntity);
//伪装浏览器
httpPost.setHeader("User-Agent",
"Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36");
CloseableHttpResponse response = null;
try {
// 执行请求
response = httpclient.execute(httpPost);
// 判断返回状态是否为200
if (response.getStatusLine().getStatusCode() == 200) {
String content = EntityUtils.toString(response.getEntity(), "UTF-8");
//内容写入文件
FileUtils.writeStringToFile(new File("E:\\devtest\\oschina-param.html"), content, "UTF-8");
System.out.println("内容长度:"+content.length());
}
} finally {
if (response != null) {
response.close();
}
httpclient.close();
}
}
}

总结

本文介绍了HttpClient的特性,是按照官方英文文档翻译而来,然后分别介绍了HttpGet和HttpPost的一般使用步骤,最后给出了4个简单的实例的Java代码。下一章节我们会介绍HttpClient连接池管理以及Spring整合HttpClient的具体过程。

二、HttpClient 学习记录---URIBuilder

https://blog.csdn.net/wxy1234556/article/details/79022402

构造函数
  URIBuilder()
  URIBuilder(final String string) 内部会创建URI对象
  URIBuilder(final URI uri)
非空的两个构造实际内部都调用了digestURI(uri) 将URI对象解析并赋值给类的属性
类属性

 String url = "http://www.google.com/search?hl=en&q=httpclient&btnG=Google+Search&aq=f&oq=";
URIBuilder uriBuilder = new URIBuilder(url);
System.out.println(uriBuilder.getScheme());
System.out.println(uriBuilder.getUserInfo());
System.out.println(uriBuilder.getHost());
System.out.println(uriBuilder.getPort());
System.out.println(uriBuilder.getPath());
System.out.println(uriBuilder.getQueryParams());
System.out.println(uriBuilder.getFragment());
System.out.println(uriBuilder.getCharset());

输出如下所示:
scheme:http
userinfo:null
host:www.google.com
prot:-1 端口默认是80,当显示指定端口时,此处便能取到值
path:/search
queryParams:[hl=en, q=httpclient, btnG=Google Search, aq=f, oq=]
fragment:null
charset:null
某些属性含义未知手动设置一次

 String url = "http://info.sporttery.cn/football/info/fb_match_hhad.php?m=102909";
URIBuilder uriBuilder = new URIBuilder(url);
uriBuilder.setFragment("111");
uriBuilder.setUserInfo("222", "333");
uriBuilder.setCharset(new GBK());
System.out.println(uriBuilder.build());
System.out.println(uriBuilder.getScheme());
System.out.println(uriBuilder.getUserInfo());
System.out.println(uriBuilder.getHost());
System.out.println(uriBuilder.getPath());
System.out.println(uriBuilder.getQueryParams());
System.out.println(uriBuilder.getFragment());
System.out.println(uriBuilder.getCharset());

输出如下:
http://222:333@info.sporttery.cn/football/info/fb_match_hhad.php?m=102909#111
scheme:http
userInfo:222:333 没见过这东西-。-
host:info.sporttery.cn
path:/football/info/fb_match_hhad.php
queryParams:[m=102909]
fragment:111 路由
charset:GBK

常用方法
URIBuilder setParameters(final List nvps)
URIBuilder addParameters(final List nvps)
URIBuilder setParameters(final NameValuePair… nvps)
上面这三个方法中我觉得俩set其实是一样的

 String url = "http://info.sporttery.cn/football/info/fb_match_hhad.php?m=102909";
URIBuilder uriBuilder = new URIBuilder(url);
ArrayList<NameValuePair> objects = new ArrayList<>();
ArrayList<NameValuePair> objects1 = new ArrayList<>();
NameValuePair m = new BasicNameValuePair("m", "1");
objects.add(m);
NameValuePair m1 = new BasicNameValuePair("m", "8");
objects1.add(m1);
uriBuilder.setParameters(objects);
uriBuilder.addParameters(objects1);
System.out.println(uriBuilder.build());

输出:http://info.sporttery.cn/football/info/fb_match_hhad.php?m=1&m=8
得出结论:set会覆盖原来的同名参数而add不会

 URIBuilder addParameter(final String param, final String value)
URIBuilder setParameter(final String param, final String value) String url = "http://info.sporttery.cn/football/info/fb_match_hhad.php?m=102909";
URIBuilder uriBuilder = new URIBuilder(url);
uriBuilder.setParameter("m", "2");
uriBuilder.addParameter("m" ,"5");
System.out.println(uriBuilder.build());

输出:http://info.sporttery.cn/football/info/fb_match_hhad.php?m=2&m=5
得出结论:set会覆盖原来的同名参数而add不会

 URIBuilder clearParameters()

 String url = "http://info.sporttery.cn/football/info/fb_match_hhad.php?m=102909";
URIBuilder uriBuilder = new URIBuilder(url);
uriBuilder.clearParameters();
System.out.println(uriBuilder.build());

输出:http://info.sporttery.cn/football/info/fb_match_hhad.php
就是清除所有参数

NameValuePair
只有一个实现类BasicNameValuePair就是用来设置参数键值对BasicNameValuePair(final String name, final String value)

NameValuePair的用法

定义了一个list,该list的数据类型是NameValuePair(简单名称值对节点类型),这个代码多处用于Java像url发送Post请求。在发送post请求时用该list来存放参数。
发送请求的大致过程如下:

String url="http://www.baidu.com";

HttpPost httppost=new HttpPost(url); //建立HttpPost对象

List<NameValuePair> params=new ArrayList<NameValuePair>();
//建立一个NameValuePair数组,用于存储欲传送的参数

params.add(new BasicNameValuePair("pwd","2544"));
//添加参数

httppost.setEntity(new UrlEncodedFormEntity(params,HTTP.UTF_8));
//设置编码

HttpResponse response=new DefaultHttpClient().execute(httppost);
//发送Post,并返回一个HttpResponse对象

https://www.cnblogs.com/hunt/p/7071053.html

httpclient使用-get-post-传参的更多相关文章

  1. HttpClient调用doGet、doPost、JSON传参及获得返回值

    调用 doPost:map传参 Map<String,Object> map = new HashMap<>(); map.put("test"," ...

  2. WebApi传参总动员(四)

    前文介绍了Form Data 形式传参,本文介绍json传参. WebApi及Model: public class ValuesController : ApiController { [HttpP ...

  3. WebApi传参总动员(三)

    上篇介绍了如何从输入流中获取实体对象.本篇介绍以url形式传递参数.简单的参数不再赘述,这里主要实现形如(string name,Woman woman)这样的参数传递. 本篇及后面几章均涉及js调用 ...

  4. 利用WCF与Android实现图片上传并传参

    利用WCF与Android实现图片上传并传参 最近做一个项目后端使用WCF接收Android手机拍照并带其它参数保存到服务器里:刚好把最近学习的WCF利用上,本以为是个比较简单的功能应该很好实现,没想 ...

  5. ASP.NET WebAPI RC 竟然不支持最常用的json传参

    壮士断腕(WCF Web API),为的是 ASP.NET Web API 的横空出世,再加上它的开放(开源),于是对之产生了一点点痴情,并写下了HttpClient + ASP.NET Web AP ...

  6. Oracle 用Drapper进行like模糊传参查询需要在参数值前后带%符合

    Oracle 用Drapper进行like模糊传参查询需要在参数值前后带%符合   string sqlstr="select * from tblname where name like ...

  7. Angular页面传参的四种方法

    1. 基于ui-router的页面跳转传参 (1)在Angular的app.js中用ui-route定义路由,比如有两个页面, 一个页面(producers.html)放置了多个producers,点 ...

  8. 使用java传参调用exe并且获取程序进度和返回结果的一种方法

    文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/ 1.背景 在某个项目中需要考虑使用java后台调用由C#编写的切图程序( ...

  9. Oracle Sales Cloud:报告和分析(BIEE)小细节2——利用变量和过滤器传参(例如,根据提示展示不同部门的数据)

    在上一篇随笔中,我们建立了部门和子部门的双提示,并将部门和子部门做了关联.那么,本篇随笔我们重点介绍利用建好的双提示进行传参. 在操作之前,我们来看一个报告和分析的具体需求: [1] 两个有关联的提示 ...

  10. js动态绑定click事件时function传参问题

    今天碰到了这样一个问题,我在javascript中动态创建了一个button, 然后我想给改button添加click事件,绑定的function想要传入一个变量参数, 一开始我想直接通过函数传参传进 ...

随机推荐

  1. MAKEFILE_LIST/CURDIR/MAKECMDGOALS/MAKEOVERRIDES/MAKEFLAGS

    http://blog.chinaunix.net/uid-29460203-id-4191975.html https://www.xuebuyuan.com/1148403.html?mobile ...

  2. 在java中使用FFmpeg处理视频与音频

    FFmpeg是一个非常好用的视频处理工具,下面讲讲如何在java中使用该工具类. 一.首先,让我们来认识一下FFmpeg在Dos界面的常见操作 1.拷贝视频,并指定新的视频的名字以及格式 ffmpeg ...

  3. 2019 ICPC徐州网络赛 E. XKC's basketball team(二分)

    计蒜客题目链接:https://nanti.jisuanke.com/t/41387 题目大意:给定一组无序序列,从第一个数开始,求最远比这个数大m的数,与这个数之间相隔多少数字?如果没有输出-1,否 ...

  4. Linux netstat命令详解(检验本机各端口的网络连接情况)

    netstat命令用于显示与IP.TCP.UDP和ICMP协议相关的统计数据,一般用于检验本机各端口的网络连接情况.netstat是在内核中访问网络及相关信息的程序,它能提供TCP连接,TCP和UDP ...

  5. PHP导出身份证号科学计数法

    最近在做PHP的数据导入和导出,到处身份证号的时候,直接变成了科学计算法,找了一个很简单的方法就是这样 $obj= " ".$v['idcard']; 但是这样有空格啊,网上搜了一 ...

  6. 09day vi命令详解

    vi有三种模式(互相切换) 1. 命令模式 2. 插入模式(编辑模式) 3. 低行模式 三种模式的切换方法: 使用技巧 vi 文件信息 i --- 进入编辑模式 esc --- 退出编辑模式 :wq ...

  7. 吴裕雄 python 机器学习——集成学习梯度提升决策树GradientBoostingRegressor回归模型

    import numpy as np import matplotlib.pyplot as plt from sklearn import datasets,ensemble from sklear ...

  8. 【笔记】Linux进程间同步和进程绑定至特定cpu

    #define _GNU_SOURCE #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> ...

  9. [lua]紫猫lua教程-命令宝典-L1-01-05. if判断结构

    L1[if]01. 简单的if判断结构 没什么说得 if得基本结构如下 xxx= ) then testlib.traceprint("1-100") ) then testlib ...

  10. js 页面滚动到指定位置

    当页面的长度比较长时,如果进行刷新页面,我们希望能够在刷新完成页面之后,能够停留在当前位置,而不是从头再手动滚动到当前位置. 那么这样的效果如何实现呢?下面开始简单描写(由于博客园不支持效果展示,所以 ...