HttpClient的操作

/**
 * 引入的依赖
 * 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&param2=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-v4.5官方文档翻译

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值