HttpClient的入门使用

时间:2021-03-20 15:57:45

本章使用HttpClient4.5.5完成访问定点网站的简单的功能。

pom文件:

<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>4.5.5</version>
</dependency>
<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpmime</artifactId>
    <version>4.5.5</version>
</dependency>


定义Request和Response:

import lombok.Data;
import java.util.*;

@Data
public class Request {
    private String id;
    private String url;
    private Method method;
    private Map<String, String> headers;
    private Map<String, String> params = new HashMap<>();

    public Request(String id, String url, Method method){
        this.id = id;
        this.url = url;
        this.method = method;
        this.headers = new HashMap<>();
    }

    public void addHeader(String key, String value){
        headers.put(key, value);
    }
}
import lombok.Data;
import org.apache.http.Header;

import java.util.ArrayList;
import java.util.List;

@Data
public class Response {
    private int statusCode;
    private String content;
    private Request request;
    private List<Header> headers =  new ArrayList<>();
}

public enum  Method {
    get,
    post;

    Method() {}
}


接口定义:

import com.demo.net.model.Request;
import com.demo.net.model.Response;

import java.io.IOException;

public interface HttpClient {
    Response execute(Request request) throws IOException;
}


具体实现类:

import com.demo.net.HttpClient;
import com.demo.net.model.Request;
import com.demo.net.model.Response;
import org.apache.commons.collections.MapUtils;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpMessage;
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.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.CharArrayBuffer;
import org.apache.http.util.EntityUtils;
import org.springframework.util.Assert;

import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Map;

public class ConcreteHttpClient implements HttpClient {

    @Override
    public Response execute(Request request) throws IOException {
        Assert.notNull(request, "invalid request");

        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpResponse closeableHttpResponse = null;
        Response response = new Response();

        try {
            switch (request.getMethod()){
                case get:
                    closeableHttpResponse = httpClient.execute(assembleHttpGet(request));
                    break;
                case post:
                    closeableHttpResponse = httpClient.execute(assembleHttpPost(request));
                    break;
                default:
                    throw new RuntimeException("未知请求");
            }

            if(closeableHttpResponse != null){
                response.setRequest(request);
                response.setStatusCode(closeableHttpResponse.getStatusLine().getStatusCode());
                response.setContent(entityToString(closeableHttpResponse.getEntity()));

                for (Header header : closeableHttpResponse.getAllHeaders()){
                    response.getHeaders().add(header);
                }
            }
        }catch (Exception e){
            throw e;
        }finally {
            if (closeableHttpResponse != null){
                closeableHttpResponse.close();
            }

            httpClient.close();
        }

        return response;
    }

    /**
     * get请求包装
     * @param request
     * @return
     */
    private HttpGet assembleHttpGet(Request request){
        HttpGet httpGet = new HttpGet(request.getUrl());
        setHeaders(httpGet, request.getHeaders());
        return httpGet;
    }

    /**
     * post请求包装
     * @param request
     * @return
     */
    private HttpPost assembleHttpPost(Request request){
        HttpPost httpPost = new HttpPost(request.getUrl());
        setHeaders(httpPost, request.getHeaders());
        return httpPost;
    }

    /**
     * 设置headers
     * @param httpMessage
     * @param headers
     */
    private void setHeaders(HttpMessage httpMessage, Map<String, String> headers){
        if (MapUtils.isNotEmpty(headers)){
            for (Map.Entry<String, String> entry : headers.entrySet()){
                httpMessage.setHeader(entry.getKey(), entry.getValue());
            }
        }
    }

    private String entityToString(HttpEntity entity) throws IOException {
        String result = null;
        if(entity != null){
            long lenth = entity.getContentLength();
            if(lenth != -1 && lenth < 2048){
                result = EntityUtils.toString(entity,"UTF-8");
            }else {
                InputStreamReader reader1 = new InputStreamReader(entity.getContent(), "UTF-8");
                CharArrayBuffer buffer = new CharArrayBuffer(2048);
                char[] tmp = new char[1024];
                int l;
                while((l = reader1.read(tmp)) != -1) {
                    buffer.append(tmp, 0, l);
                }
                result = buffer.toString();
            }
        }
        return result;
    }
}


打开目标网站,查看发起请求的request信息,复制。

HttpClient的入门使用

测试:

public static void main(String[] args) throws IOException {
        HttpClient httpClient = new ConcreteHttpClient();

        Request request = new Request("test", "https://www.baidu.com", Method.get);
        request.addHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8");
        request.addHeader("Accept-Language", "zh-CN");
        request.addHeader("Accept-Encoding", "gzip, deflate");
        request.addHeader("Host", "www.baidu.com");
        request.addHeader("Connection", "Keep-Alive");
        request.addHeader("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.162 Safari/537.36");

        Response response = httpClient.execute(request);
        System.out.println(response.getContent());
    }