一、目前JAVA实现HTTP请求的方法用的最多的有两种:
通过HTTPClient这种第三方开源框架去实现。HTTPClient对HTTP的封装性比较不错,基本上能够满足我们大部分的需求,最新的HttpClient4.5是org.apache.http.impl.client下操作远程 url的工具包;HttpClient3.1 是 org.apache.commons.httpclient下操作远程 url的工具包,虽然已不再更新,但实现工作中使用httpClient3.1的代码还是有不少的.
另一种则是通过HttpURLConnection去实现,HttpURLConnection是JAVA的标准类,是JAVA比较原生的一种实现方式。不要用这个了,有现成的工具为什么不用呢.
二、依赖
使用httpclient之前,先引入maven依赖:
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.9</version>
</dependency>
三、HttpClient 之 URIBuilder
构造函数
URIBuilder()
URIBuilder(final String string) 内部会创建URI对象: digestURI(new URI(string))
URIBuilder(final URI uri)
非空的两个构造实际内部都调用了digestURI(uri) 将URI对象解析并赋值给类的属性.
URIBuilder类中方法:
① get相关方法
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
port:-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
② 添加URI query参数方法
常用方法
setParameters(final List nvps)
setParameters(final NameValuePair… nvps)
addParameters(final List nvps)
上面的方法我觉得俩set其实是一样的, set会覆盖原来的同名参数而add不会
这里的NameValuePair :
只有一个实现类BasicNameValuePair就是用来设置参数键值对BasicNameValuePair(final String name, final String value)
String url = "http://ads-mediation.internal.zkq.sg/media/app?m=102909";
URIBuilder uriBuilder = new URIBuilder(url);
ArrayList<NameValuePair> objects = new ArrayList<>();
NameValuePair m = new BasicNameValuePair("m", "1");
objects.add(m);
ArrayList<NameValuePair> objects1 = new ArrayList<>();
NameValuePair m1 = new BasicNameValuePair("m", "8");
objects1.add(m1);
uriBuilder.setParameters(objects);
uriBuilder.addParameters(objects1);
System.out.println(uriBuilder.build());
输出:http://ads-mediation.internal.zkq.sg/media/app?m=1&m=8
得出结论:set会覆盖原来的同名参数而add不会
addParameter(final String param, final String value)
setParameter(final String param, final String value)
param和value会在这俩个方法内部组装成BasicNameValuePair.
String url = "hhttp://ads-mediation.internal.zkq.sg/media/app?m=102909";
URIBuilder uriBuilder = new URIBuilder(url);
uriBuilder.setParameter("m", "2");
uriBuilder.addParameter("m" ,"5");
System.out.println(uriBuilder.build());
输出:http://ads-mediation.internal.zkq.sg/media/app?m=2&m=5
得出结论:set会覆盖原来的同名参数而add不会
③ Clears URI query parameters.
- clearParameters() 清除所有参数 (即?后的键值对)
String url = "http://ads-mediation.internal.zkq.sg/media/app?m=102909";
URIBuilder uriBuilder = new URIBuilder(url);
uriBuilder.clearParameters();
System.out.println(uriBuilder.build());
输出:http://ads-mediation.internal.zkq.sg/media/app
四、HttpClient之基本使用步骤:
使用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. 释放连接。无论执行方法是否成功,都必须释放连接
五、HttpClient之基本get用法
public class HttpClientDemo {
public void getRequest(String url) throws URISyntaxException, IOException {
//创建httpClient实例
CloseableHttpClient client = HttpClients.createDefault();
//创建一个uri对象
URIBuilder uriBuilder = new URIBuilder(url);
//塞入form参数
uriBuilder.addParameter("account", "123");
uriBuilder.addParameter("password", "123");
//创建httpGet远程连接实例,这里传入目标的网络地址
HttpGet httpGet = new HttpGet(uriBuilder.build());
// 设置请求头信息,鉴权(没有可忽略)
httpGet.setHeader("Authorization", "Bearer da3efcbf-0845-4fe3-8aba-ee040be542c0");
// 设置配置请求参数(没有可忽略)
RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(35000)// 连接主机服务超时时间
.setConnectionRequestTimeout(35000)// 请求超时时间
.setSocketTimeout(60000)// 数据读取超时时间
.build();
// 为httpGet实例设置配置
httpGet.setConfig(requestConfig);
//执行请求
CloseableHttpResponse response = client.execute(httpGet);
//获取Response状态码
int statusCode = response.getStatusLine().getStatusCode();
System.out.println(statusCode);
//获取响应实体, 响应内容
HttpEntity entity = response.getEntity();
//通过EntityUtils中的toString方法将结果转换为字符串
String str = EntityUtils.toString(entity);
System.out.println(str);
response.close();
client.close();
}
}
(如果用try catch 记得关闭资源)
六、HttpClient之post - json用法
public String postRequest(String url, Map<String, Object> paramMap) {
HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
// 创建httpPost远程连接实例
HttpPost post = new HttpPost(url);
String result = "";
try (CloseableHttpClient closeableHttpClient = httpClientBuilder.build()) {
// HttpEntity entity = new StringEntity(jsonDataStr);
// 修复 POST json 导致中文乱码
HttpEntity entity = new StringEntity(paramMap.toString(), "UTF-8");
post.setEntity(entity);
post.setHeader("Content-type", "application/json");
HttpResponse resp = closeableHttpClient.execute(post);
try {
InputStream respIs = resp.getEntity().getContent();
byte[] respBytes = IOUtils.toByteArray(respIs);
result = new String(respBytes, Charset.forName("UTF-8"));
} catch (Exception e) {
e.printStackTrace();
}
return result;
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
七、HttpClient之post - form用法
form的关键在于生成NameValuePair ,这个集合里面放入form 表单的元素.
随后使用 HttpPost 的 setEntity(new UrlEncodedFormEntity(nameValuePair, HTTP.UTF_8)) 方法塞入生成的form元素集合.
总得来说, 就是通过一个NameValuePair集合来存放待提交的参数,并将这个参数集合传入到一个UrlEncodedFormEntity中,然后调用HttpPost的setEntity()方法将构建好的UrlEncodedFormEntity传入. 代码如下:
List<NameValuePair>params=newArrayList<NameValuePair>();
Params.add(new BasicNameValuePair(“username”,”admin”));
Params.add(new BasicNameValuePair(“password”,”123456”));
UrlEncodedFormEntity entity=newUrlEncodedFormEntity(params,”utf-8”);
httpPost.setEntity(entity);
public static String postformRequest(String url, Map<String, Object> paramMap) {
CloseableHttpClient httpClient = null;
CloseableHttpResponse httpResponse = null;
String result = "";
// 创建httpClient实例
httpClient = HttpClients.createDefault();
// 创建httpPost远程连接实例
HttpPost httpPost = new HttpPost(url);
// 配置请求参数实例(不需要可忽略)
RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(35000)// 设置连接主机服务超时时间
.setConnectionRequestTimeout(35000)// 设置连接请求超时时间
.setSocketTimeout(60000)// 设置读取数据连接超时时间
.build();
// 为httpPost实例设置配置(不需要可忽略)
httpPost.setConfig(requestConfig);
// 设置请求头
httpPost.addHeader("Content-Type", "application/x-www-form-urlencoded");
// 封装表单参数
if (null != paramMap && paramMap.size() > 0) {
// 以下代码使用实现类BasicNameValuePair生成NameValuePair
List<NameValuePair> nvps = new ArrayList<NameValuePair>();
// 通过map集成entrySet方法获取entity
Set<Entry<String, Object>> entrySet = paramMap.entrySet();
// 循环遍历,获取迭代器
Iterator<Entry<String, Object>> iterator = entrySet.iterator();
while (iterator.hasNext()) {
Entry<String, Object> mapEntry = iterator.next();
nvps.add(new BasicNameValuePair(mapEntry.getKey(), mapEntry.getValue().toString()));
}
// 为httpPost设置封装好的请求参数
try {
// post实例塞参数的方法
httpPost.setEntity(new UrlEncodedFormEntity(nvps, "UTF-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
try {
// 服务器返回的所有信息都在HttpResponse中, httpClient对象执行post请求,并返回响应参数对象
httpResponse = httpClient.execute(httpPost);
// 先取出服务器返回的状态码,如果等于200说明success
int code =httpResponse.getStatusLine().getStatusCode();
// 从响应对象中获取响应内容
// EntityUtils.toString()有重载方法
// 这个静态方法将HttpEntity转换成字符串,防止服务器返回的数据带有中文,所以在转换的时候将字符集指定成utf-8即可
HttpEntity entity = httpResponse.getEntity();
result = EntityUtils.toString(entity,"UTF-8");
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
// 关闭资源
if (null != httpResponse) {
try {
httpResponse.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (null != httpClient) {
try {
httpClient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return result;
}
}