/**
* 引入的依赖
* compile group: 'org.apache.httpcomponents', name: 'httpclient', version: '4.5.9'
* compile group: 'org.apache.httpcomponents', name: 'httpcore', version: '4.4.13'
*
* HttpClient相关知识
* 0 使用的资源记得关闭
* 1 HTTP请求
* HTTP请求行 = 方法名 + URI + HTTP协议版本 1.1
* HttpClient支持的HTTP方法:GET,HEAD,POST,PUT,DELETE,TRACE和OPTIONS
* 对应的特定类:HttpGet,HttpHead,HttpPost,HttpPut,HttpDelete,HttpTrace和HttpOptions
* Request-URI:协议方案 + 主机名 + 可选的端口 + 资源路径 + 可选的查询和可选的片段
* http://www.google.com/search?hl=en&q=httpclient&btnG=Google+Search&aq=f&oq=;
* 可以使用URIBuilder实用程序类来简化请求URI的创建和修改
* 2 HTTP响应
* HTTP响应的第一行 = 协议版本 + 数字状态码 + 相关的文本短语(使用HttpResponse自带的方法进行获取)
* HTTP响应头中的信息,使用Header对象获取(可以使用BasicHttpResponse来模拟HTTP Header)
* 3 HTTP Entity
* HTTP内容实体中ByteArrayEntity或StringEntity可以被多次读取.同时支持字符编码
* HTTPEntity的getContent()获取InputStream,读进输入流(可以使用getContentType()和getContentLength()获取数据的类型和长度)
* writeTo()获取OutputStream,写进输出流
* getContentEncoding()获取text/plain等的编码类型
* EntityUtils可以读取实体的内容,但最好不要用,除非响应实体被信任且长度有限.
* BufferedHttpEntity可以将响应实体缓冲到内存缓冲区.其他与原始实体无异
* 4 创建发送的消息体
* 字符串 StringEntity
* 字节数组 ByteArrayEntity
* 输入流 InputStreamEntity
* 文件 FileEntity
* 5 HttpClient接口,用于扩展HttpClient的一些功能(https://blog.csdn.net/zhongzh86/article/details/84070561搜 HttpClient 接口)
*/
package xyz.lightly.dragform;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URI;
import java.net.URISyntaxException;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;
import org.apache.http.Consts;
import org.apache.http.Header;
import org.apache.http.HeaderElement;
import org.apache.http.HeaderElementIterator;
import org.apache.http.HeaderIterator;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.HttpVersion;
import org.apache.http.NameValuePair;
import org.apache.http.ParseException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.CookieStore;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
import org.apache.http.cookie.Cookie;
import org.apache.http.entity.BufferedHttpEntity;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.FileEntity;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.cookie.BasicClientCookie;
import org.apache.http.message.BasicHeaderElementIterator;
import org.apache.http.message.BasicHttpResponse;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.apache.http.ssl.SSLContexts; // SSLContexts需要导入httpcore包中的类
public class HttpClientDemo {
/**
* 进行HttpClient的请求,获取响应体
*
* @throws IOException
* @throws ClientProtocolException
* @throws URISyntaxException
*/
public static void doHttpRequest() throws ClientProtocolException, IOException, URISyntaxException {
// 创建HttpClient对象
CloseableHttpClient httpClient = HttpClients.createDefault();
// 创建URI对象,也可以直接使用字符串定义出来,效果一样。这样更方便修改,也更清晰。
/*
* 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();
*/
URI uri = new URIBuilder().setScheme("http").setHost("www.baidu.com").build();
// 创建请求方法的实例。并指定请求URL。如果需要发送GET请求,创建HttpGet对象;如果需要发送POST请求,创建HttpPost对象
HttpGet httpGet = new HttpGet(uri);
// 设置请求头
httpGet.setHeader("Content-type", "application/x-www-form-urlencoded");
// 设置请求体,post才有请求体
// requestMesssageEntityOfFile(httpPost);
// 获取请求的响应对象。通过httpClient对象执行httpGet的请求即可.这里的请求资源需要进行关闭
CloseableHttpResponse response = httpClient.execute(httpGet);
StringBuilder result = new StringBuilder();
try {
// 获取响应对象的响应实体
HttpEntity entity = response.getEntity();
if (entity != null) {
BufferedReader reader = null;
try {
// 将响应内容读入到BufferedReader里边
reader = new BufferedReader(new InputStreamReader(entity.getContent(), "UTF-8"));
// 将读入的数据写入StringBuilder
String lines;
// 用lines一行一行接收读取回来的数据,如果仍有数据,则不为null,把数据写入StringBuilder中
while ((lines = reader.readLine()) != null) {
result.append(lines);
}
} finally {
if (reader != null)
reader.close();
}
/*
* 也可以使用EntityUtils类.如果长度不是-1,可以直接获取.但是HTML网页响应的就是-1 long len =
* entity.getContentLength(); if (len != -1 && len < 2048) {
* System.out.println(EntityUtils.toString(entity)); }
*/
}
} finally {
if (response != null)
response.close(); // 关闭HTTP连接资源
if (httpClient != null)
httpClient.close();
}
System.out.println(result);
}
/**
* 获取httpClient的response对象响应第一行的内容
*/
public static void getHttpClientResponseFirstLine() {
// 创建响应对象。参数一 协议版本, 参数二 数字状态码, 参数三 文本短语
HttpResponse response_1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
// 获取响应对象的协议版本
System.out.println(response_1.getProtocolVersion());
// 获取响应对象的状态码
System.out.println(response_1.getStatusLine().getStatusCode());
// 获取响应对象的状态信息
System.out.println(response_1.getStatusLine().getReasonPhrase());
// 将所有信息在一行中进行输出
System.out.println(response_1.getStatusLine().toString());
}
/**
* 设置并获取响应头中的信息
*/
public static void setAndGetHttpClientResponseHeader() {
// 创建响应对象。参数一 协议版本, 参数二 数字状态码, 参数三 文本短语
HttpResponse response_1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
// 添加不同的header
// 设置cookie,且可以同时设置多个
response_1.addHeader("Set-Cookie", "c1=a; path=/; domain=localhost");
// 在双引号前边加上转义反斜杠,可以在cookie中存放双引号
response_1.addHeader("Set-Cookie", "c2=b; path=\"/\", c3=c; domain=\"localhost\"");
// 获取响应头信息
// 获取第一个头信息
Header h1 = response_1.getFirstHeader("Set-Cookie");
System.out.println(h1);
// 获取最后一个头信息
Header h2 = response_1.getLastHeader("Set-Cookie");
System.out.println(h2);
// 获取Header中消息的数量
Header[] hs = response_1.getHeaders("Set-Cookie");
System.out.println(hs.length);
// 获取Header某个键中值的迭代器
HeaderIterator it = response_1.headerIterator();
// 使用迭代器进行迭代操作
while (it.hasNext()) {
System.out.println(it.next());
}
}
/**
* 获取httpClient的response的header对象中的单个元素
*/
public static void getHttpClientSingleParamOfResponse() {
// 创建响应对象。参数一 协议版本, 参数二 数字状态码, 参数三 文本短语
HttpResponse response_1 = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
// 添加不同的header
// 设置cookie,且可以同时设置多个
response_1.addHeader("Set-Cookie", "c1=a; path=/; domain=localhost");
// 在双引号前边加上转义反斜杠,可以在cookie中存放双引号
response_1.addHeader("Set-Cookie", "c2=b; path=\"/\", c3=c; domain=\"localhost\"");
// 将获取的header键的值拆分开,每次只获取里边的一个单值
HeaderElementIterator it = new BasicHeaderElementIterator(response_1.headerIterator());
while (it.hasNext()) {
HeaderElement elem = it.nextElement();
// 输出键值
System.out.println(elem.getName() + ":" + elem.getValue());
// path和domain不能拆分,所以只能赋值给NameValuePair输出
NameValuePair[] params = elem.getParameters();
for (int i = 0; i < params.length; i++) {
System.out.println(" " + params[i]);
}
}
// 通过Header来遍历响应头
Header[] header = response_1.getAllHeaders();
for (int i = 0; i < header.length; i++) {
System.out.println(header[i].getName() + header[i].getValue());
}
}
/**
* HttpClient的request和response的实体操作
*/
public static void doHttpEntityOperation() throws ParseException, IOException {
// 创建实体对象,可以传入消息和类型编码
StringEntity myEntity = new StringEntity("important message", ContentType.create("text/plain", "UTF-8"));
// 获取ContentType和ContentLength,并与EntityUtils转换后的数据进行一下比较
System.out.println(myEntity.getContentType());
System.out.println(myEntity.getContentLength());
System.out.println(EntityUtils.toString(myEntity));
System.out.println(EntityUtils.toByteArray(myEntity).length);
}
/**
* 当响应实体需要被多次访问的时候可以用BufferedHttpEntity缓冲到内存
*/
public static void memorizeHttpEntity(HttpEntity entity) throws IOException {
if (entity != null) {
entity = new BufferedHttpEntity(entity);
}
}
/**
* 从文件中读取数据,然后插入到请求体中, 也可以使用StringEntity,ByteArrayEntity,InputStreamEntity
*
* @param HttpPost httoPost post请求的对象
*/
public static void requestMesssageEntityOfFile(HttpPost httpPost) {
File file = new File("somefile.txt");
FileEntity entity = new FileEntity(file, ContentType.create("text/plain", "UTF-8"));
httpPost.setEntity(entity);
}
/**
* 使用表单创建请求体 也可以使用StringEntity,ByteArrayEntity,InputStreamEntity
*
* @param HttpPost httoPost post请求的对象
*/
public static void requestMesssageEntityOfForm(HttpPost httpPost) {
// 创建表单list,里边存放键值对的NameValuePair对象
List<NameValuePair> formparams = new ArrayList<NameValuePair>();
// 添加表单的数据,以BasicNameValuePair对象的形式添加
formparams.add(new BasicNameValuePair("param1", "value1"));
formparams.add(new BasicNameValuePair("param2", "value2"));
// 将表单数据编码,然后组装成entity.最后的结果类似param1=value1¶m2=value2
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(formparams, Consts.UTF_8);
httpPost.setEntity(entity);
}
/**
* 实现ResponseHandler接口,可以在进行响应处理的时候更简单的操作.而且不必关闭响应资源
* 在https://blog.csdn.net/zhongzh86/article/details/84070561搜handleResponse
*/
/**
* 在httpClient中设置cookie
*/
public static void httpClientSetCookie() {
// 创建cookieStore实例
CookieStore cookieStore = new BasicCookieStore();
// 创建cookie,并填入相应的键值,域名,路径,添加到cookieStore中.也可以创建cookie
BasicClientCookie cookie = new BasicClientCookie("name", "value");
cookie.setDomain(".mycompany.com");
cookie.setPath("/");
cookieStore.addCookie(cookie);
// 将cookieStore链接到创建的httpClient上.如果返回有cookie,也会在cookieStore中进行记录
CloseableHttpClient httpclient = HttpClients.custom().setDefaultCookieStore(cookieStore).build();
// 执行代码,得到响应,这里可以获取到相应的cookie
List<Cookie> cookies = cookieStore.getCookies();
// 判断cookie不为空,那么可以获取到该cookie,然后进行其他操作
/*
* if (null != cookies && cookies.size() > 0) { javax.servlet.http.Cookie cookie
* = new javax.servlet.http.Cookie(cookies.get(0).getName(),
* cookies.get(0).getValue()); cookie.setPath(cookies.get(0).getPath());
* cookie.setHttpOnly(true); cookie.setSecure(true); cookie.setMaxAge(1800);
* responses.addCookie(cookie); }
*/
}
public static void useHttpClientHttps() throws KeyManagementException, NoSuchAlgorithmException, KeyStoreException {
SSLConnectionSocketFactory scsf = new SSLConnectionSocketFactory(
SSLContexts.custom().loadTrustMaterial(null, new TrustSelfSignedStrategy()).build(),
NoopHostnameVerifier.INSTANCE);
CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(scsf).build();
}
public static void main(String[] args) {
try {
doHttpRequest();
// getHttpClientResponseFirstLine();
// setAndGetHttpClientResponseHeader();
// getHttpClientSingleParamOfResponse();
// doHttpEntityOperation();
} catch ( Exception e) {
e.printStackTrace();
}
}
}
HttpClient的操作
最新推荐文章于 2024-04-17 17:43:04 发布