基于apache-httpclient 4.3封装的HttpUtils

说实话,我的文笔并不好,但是我有一颗热爱代码热爱技术的心。废话少说,言归正传。在做项目时,测试http接口时,总免不了需要请求服务器,但是这个过程用java原生写还是比较复杂的。即使现在有了apache-httpclient,但是对于一些比较复杂的操作还是有些麻烦,然后为了简化代码是提高开发效率,就基于httpclient4.3封装了这么两个工具类。直接上代码:

HttpUtils类,很简单,就是用来请求服务器的

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.net.InetAddress;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.charset.Charset;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.net.ssl.SSLContext;

import org.apache.http.Consts;
import org.apache.http.Header;
import org.apache.http.HeaderIterator;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.NameValuePair;
import org.apache.http.ProtocolVersion;
import org.apache.http.client.CookieStore;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.config.CookieSpecs;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.config.RequestConfig.Builder;
import org.apache.http.client.entity.EntityBuilder;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.conn.socket.LayeredConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLContextBuilder;
import org.apache.http.conn.ssl.SSLContexts;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.cookie.Cookie;
import org.apache.http.entity.ContentType;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.DefaultProxyRoutePlanner;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicNameValuePair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.core.JsonParser.Feature;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;

public class HttpUtils {
    
    private static Logger logger = LoggerFactory.getLogger(HttpUtils.class);
    
    private HttpRequestBase request; //请求对象
    private EntityBuilder builder; //Post, put请求的参数
    private URIBuilder uriBuilder; //get, delete请求的参数
    private LayeredConnectionSocketFactory socketFactory; //连接工厂
    private HttpClientBuilder clientBuilder; //构建httpclient
    private CloseableHttpClient httpClient; //
    private CookieStore cookieStore; //cookie存储器
    private Builder config; //请求的相关配置
    private boolean isHttps; //是否是https请求
    private int type; //请求类型1-post, 2-get, 3-put, 4-delete

    
    
    private HttpUtils (HttpRequestBase request) {
        this.request = request;
        
        this.clientBuilder = HttpClientBuilder.create();
        this.isHttps = request.getURI().getScheme().equalsIgnoreCase("https");
        this.config = RequestConfig.custom().setCookieSpec(CookieSpecs.BROWSER_COMPATIBILITY);
        this.cookieStore = new BasicCookieStore();
        
        if (request instanceof HttpPost) {
            this.type = 1;
            this.builder = EntityBuilder.create().setParameters(new ArrayList<NameValuePair>());
            
        } else if(request instanceof HttpGet) {
            this.type = 2;
            this.uriBuilder = new URIBuilder();
            
        } else if(request instanceof HttpPut) {
            this.type = 3;
            this.builder = EntityBuilder.create().setParameters(new ArrayList<NameValuePair>());
        
        } else if(request instanceof HttpDelete) {
            this.type = 4;
            this.uriBuilder = new URIBuilder();
        }
    }
    
    private HttpUtils(HttpRequestBase request, HttpUtils clientUtils) {
        this(request);
        this.httpClient = clientUtils.httpClient;
        this.config = clientUtils.config;
        this.setHeaders(clientUtils.getAllHeaders());
        this.SetCookieStore(clientUtils.cookieStore);
    }
    
    private static HttpUtils create(HttpRequestBase request) {
        return new HttpUtils(request);
    }
    
    private static HttpUtils create(HttpRequestBase request, HttpUtils clientUtils) {
        return new HttpUtils(request, clientUtils);
    }

    /**
     * 创建post请求
     * @author mdc
     * @date 2015年7月17日
     * @param url 请求地址
     * @return
     */
    public static HttpUtils post(String url) {
        return create(new HttpPost(url));
    }
    
    /**
     * 创建get请求
     * @author mdc
     * @date 2015年7月17日
     * @param url 请求地址
     * @return
     */
    public static HttpUtils get(String url) {
        return create(new HttpGet(url));
    }
    
    /**
     * 创建put请求
     * @author mdc
     * @date 2015年7月17日
     * @param url 请求地址
     * @return
     */
    public static HttpUtils put(String url) {
        return create(new HttpPut(url));
    }
    
    /**
     * 创建delete请求
     * @author mdc
     * @date 2015年7月17日
     * @param url 请求地址
     * @return
     */
    public static HttpUtils delete(String url) {
        return create(new HttpDelete(url));
    }
    
    /**
     * 创建post请求
     * @author mdc
     * @date 2015年7月17日
     * @param uri 请求地址
     * @return
     */
    public static HttpUtils post(URI uri) {
        return create(new HttpPost(uri));
    }
    
    /**
     * 创建get请求
     * @author mdc
     * @date 2015年7月17日
     * @param uri 请求地址
     * @return
     */
    public static HttpUtils get(URI uri) {
        return create(new HttpGet(uri));
    }
    
    /**
     * 创建put请求
     * @author mdc
     * @date 2015年7月17日
     * @param uri 请求地址
     * @return
     */
    public static HttpUtils put(URI uri) {
        return create(new HttpPut(uri));
    }
    
    /**
     * 创建delete请求
     * @author mdc
     * @date 2015年7月17日
     * @param uri 请求地址
     * @return
     */
    public static HttpUtils delete(URI uri) {
        return create(new HttpDelete(uri));
    }
    
    /**
     * 创建post请求
     * @author mdc
     * @date 2015年7月17日
     * @param url 请求地址
     * @return
     */
    public static HttpUtils post(String url, HttpUtils clientUtils) {
        return create(new HttpPost(url), clientUtils);
    }
    
    /**
     * 创建get请求
     * @author mdc
     * @date 2015年7月17日
     * @param url 请求地址
     * @return
     */
    public static HttpUtils get(String url, HttpUtils clientUtils) {
        return create(new HttpGet(url), clientUtils);
    }
    
    /**
     * 创建put请求
     * @author mdc
     * @date 2015年7月17日
     * @param url 请求地址
     * @return
     */
    public static HttpUtils put(String url, HttpUtils clientUtils) {
        return create(new HttpPut(url), clientUtils);
    }
    
    /**
     * 创建delete请求
     * @author mdc
     * @date 2015年7月17日
     * @param url 请求地址
     * @return
     */
    public static HttpUtils delete(String url, HttpUtils clientUtils) {
        return create(new HttpDelete(url), clientUtils);
    }
    
    /**
     * 创建post请求
     * @author mdc
     * @date 2015年7月17日
     * @param uri 请求地址
     * @return
     */
    public static HttpUtils post(URI uri, HttpUtils clientUtils) {
        return create(new HttpPost(uri), clientUtils);
    }
    
    /**
     * 创建get请求
     * @author mdc
     * @date 2015年7月17日
     * @param uri 请求地址
     * @return
     */
    public static HttpUtils get(URI uri, HttpUtils clientUtils) {
        return create(new HttpGet(uri), clientUtils);
    }
    
    /**
     * 创建put请求
     * @author mdc
     * @date 2015年7月17日
     * @param uri 请求地址
     * @return
     */
    public static HttpUtils put(URI uri, HttpUtils clientUtils) {
        return create(new HttpPut(uri), clientUtils);
    }
    
    /**
     * 创建delete请求
     * @author mdc
     * @date 2015年7月17日
     * @param uri 请求地址
     * @return
     */
    public static HttpUtils delete(URI uri, HttpUtils clientUtils) {
        return create(new HttpDelete(uri), clientUtils);
    }
    
    /**
     * 添加参数
     * @author mdc
     * @date 2015年7月17日
     * @param parameters
     * @return
     */
    public HttpUtils setParameters(final NameValuePair ...parameters) {
        if (builder != null) {
            builder.setParameters(parameters);
        } else {
            uriBuilder.setParameters(Arrays.asList(parameters));
        }
        return this;
    }
    
    /**
     * 添加参数
     * @author mdc
     * @date 2015年7月17日
     * @param name
     * @param value
     * @return
     */
    public HttpUtils addParameter(final String name, final String value) {
        if (builder != null) {
            builder.getParameters().add(new BasicNameValuePair(name, value));
        } else {
            uriBuilder.addParameter(name, value);
        }
        return this;
    }
    
    /**
     * 添加参数
     * @author mdc
     * @date 2015年7月17日
     * @param parameters
     * @return
     */
    public HttpUtils addParameters(final NameValuePair ...parameters) {
        if (builder != null) {
            builder.getParameters().addAll(Arrays.asList(parameters));
        } else {
            uriBuilder.addParameters(Arrays.asList(parameters));
        }
        return this;
    }
    
    /**
     * 设置请求参数,会覆盖之前的参数
     * @author mdc
     * @date 2015年7月17日
     * @param parameters
     * @return
     */
    public HttpUtils setParameters(final Map<String, String> parameters) {
        NameValuePair [] values = new NameValuePair[parameters.size()];
        int i = 0;
        
        for (Entry<String, String> parameter : parameters.entrySet()) {
            values[i++] = new BasicNameValuePair(parameter.getKey(), parameter.getValue());
        }
        
        setParameters(values);
        return this;
    }
    
    /**
     * 设置请求参数,会覆盖之前的参数
     * @author mdc
     * @date 2015年7月17日
     * @param file
     * @return
     */
    public HttpUtils setParameter(final File file) {
        if(builder != null) {
            builder.setFile(file);
        } else {
            throw new UnsupportedOperationException();
        }
        return this;
    }
    
    /**
     * 设置请求参数,会覆盖之前的参数
     * @author mdc
     * @date 2015年7月17日
     * @param binary
     * @return
     */
    public HttpUtils setParameter(final byte[] binary) {
        if(builder != null) {
            builder.setBinary(binary);
        } else {
            throw new UnsupportedOperationException();
        }
        return this;
    }
    
    /**
     * 设置请求参数,会覆盖之前的参数
     * @author mdc
     * @date 2015年7月17日
     * @param serializable
     * @return
     */
    public HttpUtils setParameter(final Serializable serializable) {
        if(builder != null) {
            builder.setSerializable(serializable);
        } else {
            throw new UnsupportedOperationException();
        }
        return this;
    }
    
    /**
     * 设置参数为Json对象
     * @author mdc
     * @date 2015年7月27日
     * @param parameter 参数对象
     * @return
     */
    public HttpUtils setParameterJson(final Object parameter) {
        if(builder != null) {
            try {
                builder.setBinary(mapper.writeValueAsBytes(parameter));
            } catch (JsonProcessingException e) {
                throw new RuntimeException(e.getMessage(), e);
            }
        } else {
            throw new UnsupportedOperationException();
        }
        return this;
    }
    
    /**
     * 设置请求参数,会覆盖之前的参数
     * @author mdc
     * @date 2015年7月17日
     * @param stream
     * @return
     */
    public HttpUtils setParameter(final InputStream stream) {
        if(builder != null) {
            builder.setStream(stream);
        } else {
            throw new UnsupportedOperationException();
        }
        return this;
    }
    
    /**
     * 设置请求参数,会覆盖之前的参数
     * @author mdc
     * @date 2015年7月17日
     * @param text
     * @return
     */
    public HttpUtils setParameter(final String text) {
        if(builder != null) {
            builder.setText(text);
        } else {
            uriBuilder.setParameters(URLEncodedUtils.parse(text, Consts.UTF_8));
        }
        return this;
    }
    
    /**
     * 设置内容编码
     * @author mdc
     * @date 2015年7月17日
     * @param encoding
     * @return
     */
    public HttpUtils setContentEncoding(final String encoding) {
        if(builder != null) builder.setContentEncoding(encoding);
        return this;
    }
    
    /**
     * 设置ContentType
     * @author mdc
     * @date 2015年7月17日
     * @param contentType
     * @return
     */
    public HttpUtils setContentType(ContentType contentType) {
        if(builder != null) builder.setContentType(contentType);
        return this;
    }
    
    /**
     * 设置ContentType
     * @author mdc
     * @date 2015年7月17日
     * @param mimeType
     * @param charset 内容编码
     * @return
     */
    public HttpUtils setContentType(final String mimeType, final Charset charset) {
        if(builder != null) builder.setContentType(ContentType.create(mimeType, charset));
        return this;
    }
    
    /**
     * 添加参数
     * @author mdc
     * @date 2015年7月17日
     * @param parameters
     * @return
     */
    public HttpUtils addParameters(Map<String, String> parameters) {
        List<NameValuePair> values = new ArrayList<>(parameters.size());
        
        for (Entry<String, String> parameter : parameters.entrySet()) {
            values.add(new BasicNameValuePair(parameter.getKey(), parameter.getValue()));
        }
        
        if(builder != null) {
            builder.getParameters().addAll(values);
        } else {
            uriBuilder.addParameters(values);
        }
        return this;
    }
    
    /**
     * 添加Header
     * @author mdc
     * @date 2015年7月17日
     * @param name
     * @param value
     * @return
     */
    public HttpUtils addHeader(String name, String value) {
        request.addHeader(name, value);
        return this;
    }
    
    /**
     * 添加Header
     * @author mdc
     * @date 2015年7月17日
     * @param headers
     * @return
     */
    public HttpUtils addHeaders(Map<String, String> headers) {
        for (Entry<String, String> header : headers.entrySet()) {
            request.addHeader(header.getKey(), header.getValue());
        }
        
        return this;
    }
    
    /**
     * 设置Header,会覆盖所有之前的Header
     * @author mdc
     * @date 2015年7月17日
     * @param headers
     * @return
     */
    public HttpUtils setHeaders(Map<String, String> headers) {
        Header [] headerArray = new Header[headers.size()];
        int i = 0;
        
        for (Entry<String, String> header : headers.entrySet()) {
            headerArray[i++] = new BasicHeader(header.getKey(), header.getValue());
        }
        
        request.setHeaders(headerArray);
        return this;
    }
    
    public HttpUtils setHeaders(Header [] headers) {
        request.setHeaders(headers);
        return this;
    }
    
    /**
     * 获取所有Header
     * @author mdc
     * @date 2015年7月17日
     * @return
     */
    public Header[] getAllHeaders() {
        return request.getAllHeaders();
    }
    
    /**
     * 移除指定name的Header列表
     * @author mdc
     * @date 2015年7月17日
     * @param name
     */
    public HttpUtils removeHeaders(String name){
        request.removeHeaders(name);
        return this;
    }
    
    /**
     * 移除指定的Header
     * @author mdc
     * @date 2015年7月17日
     * @param header
     */
    public HttpUtils removeHeader(Header header){
        request.removeHeader(header);
        return this;
    }
    
    /**
     * 移除指定的Header
     * @author mdc
     * @date 2015年7月17日
     * @param name
     * @param value
     */
    public HttpUtils removeHeader(String name, String value){
        request.removeHeader(new BasicHeader(name, value));
        return this;
    }
    
    /**
     * 是否存在指定name的Header
     * @author mdc
     * @date 2015年7月17日
     * @param name
     * @return
     */
    public boolean containsHeader(String name){
        return request.containsHeader(name);
    }
    
    /**
     * 获取Header的迭代器
     * @author mdc
     * @date 2015年7月17日
     * @return
     */
    public HeaderIterator headerIterator(){
        return request.headerIterator();
    }
    
    /**
     * 获取协议版本信息
     * @author mdc
     * @date 2015年7月17日
     * @return
     */
    public ProtocolVersion getProtocolVersion(){
        return request.getProtocolVersion();
    }
    
    /**
     * 获取请求Url
     * @author mdc
     * @date 2015年7月17日
     * @return
     */
    public URI getURI(){
        return request.getURI();
    }
    
    /**
     * 设置请求Url
     * @author mdc
     * @date 2015年7月17日
     * @return
     */
    public HttpUtils setURI(URI uri){
        request.setURI(uri);
        return this;
    }
    
    /**
     * 设置请求Url
     * @author mdc
     * @date 2015年7月17日
     * @return
     */
    public HttpUtils setURI(String uri){
        return setURI(URI.create(uri));
    }
    
    /**
     * 设置一个CookieStore
     * @author mdc
     * @date 2015年7月18日
     * @param cookieStore
     * @return
     */
    public HttpUtils SetCookieStore(CookieStore cookieStore){
        if(cookieStore == null) return this;
        this.cookieStore = cookieStore;
        return this;
    }
    
    /**
     * 添加Cookie
     * @author mdc
     * @date 2015年7月18日
     * @param cookie
     * @return
     */
    public HttpUtils addCookie(Cookie ...cookies){
        if(cookies == null) return this;
        
        for (int i = 0; i < cookies.length; i++) {
            cookieStore.addCookie(cookies[i]);
        }
        return this;
    }
    
    /**
     * 设置网络代理
     * @author mdc
     * @date 2015年7月17日
     * @param hostname
     * @param port
     * @return
     */
    public HttpUtils setProxy(String hostname, int port) {
        HttpHost proxy = new HttpHost(hostname, port);
        return setProxy(proxy);
    }
    
    /**
     * 设置网络代理
     * @author mdc
     * @date 2015年7月17日
     * @param hostname
     * @param port
     * @param schema
     * @return
     */
    public HttpUtils setProxy(String hostname, int port, String schema) {
        HttpHost proxy = new HttpHost(hostname, port, schema);
        return setProxy(proxy);
    }
    
    /**
     * 设置网络代理
     * @author mdc
     * @date 2015年7月17日
     * @param address
     * @return
     */
    public HttpUtils setProxy(InetAddress address) {
        HttpHost proxy = new HttpHost(address);
        return setProxy(proxy);
    }
    
    /**
     * 设置网络代理
     * @author mdc
     * @date 2015年7月17日
     * @param host
     * @return
     */
    public HttpUtils setProxy(HttpHost host) {
        DefaultProxyRoutePlanner routePlanner = new DefaultProxyRoutePlanner(host);
        clientBuilder.setRoutePlanner(routePlanner);
        return this;
    }
    
    /**
     * 设置双向认证的JKS
     * @author mdc
     * @date 2015年7月17日
     * @param jksFilePath jks文件路径
     * @param password 密码
     * @return
     */
    public HttpUtils setJKS(String jksFilePath, String password) {
        return setJKS(new File(jksFilePath), password);
    }
    
    /**
     * 设置双向认证的JKS
     * @author mdc
     * @date 2015年7月17日
     * @param jksFile jks文件
     * @param password 密码
     * @return
     */
    public HttpUtils setJKS(File jksFile, String password) {
        try (InputStream instream = new FileInputStream(jksFile)) {
            return setJKS(instream, password);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new RuntimeException(e.getMessage(), e);
        }
    }
    
    /**
     * 设置双向认证的JKS, 不会关闭InputStream
     * @author mdc
     * @date 2015年7月17日
     * @param instream jks流
     * @param password 密码
     * @return
     */
    public HttpUtils setJKS(InputStream instream, String password) {
        try {
            KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); 
            keyStore.load(instream, password.toCharArray());
            return setJKS(keyStore);
            
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new RuntimeException(e.getMessage(), e);
        }
    }
    
    /**
     * 设置双向认证的JKS
     * @author mdc
     * @date 2015年7月17日
     * @param keyStore jks
     * @return
     */
    public HttpUtils setJKS(KeyStore keyStore) {
        try {
            SSLContext sslContext = SSLContexts.custom().useTLS().loadTrustMaterial(keyStore).build();
            socketFactory = new SSLConnectionSocketFactory(sslContext);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new RuntimeException(e.getMessage(), e);
        }
        
        return this;
    }
    
    /**
     * 设置Socket超时时间,单位:ms
     * @author mdc
     * @date 2015年7月18日
     * @param socketTimeout
     * @return
     */
    public HttpUtils setSocketTimeout(int socketTimeout){
        config.setSocketTimeout(socketTimeout);
        return this;
    }
    
    /**
     * 设置连接超时时间,单位:ms
     * @author mdc
     * @date 2015年7月18日
     * @param connectTimeout
     * @return
     */
    public HttpUtils setConnectTimeout(int connectTimeout) {
        config.setConnectTimeout(connectTimeout);
        return this;
    }
    
    /**
     * 设置请求超时时间,单位:ms
     * @author mdc
     * @date 2015年7月18日
     * @param connectionRequestTimeout
     * @return
     */
    public HttpUtils setConnectionRequestTimeout(int connectionRequestTimeout) {
        config.setConnectionRequestTimeout(connectionRequestTimeout);
        return this;
    }
    
    /**
     * 设置是否允许服务端循环重定向
     * @author mdc
     * @date 2015年7月18日
     * @param circularRedirectsAllowed
     * @return
     */
    public HttpUtils setCircularRedirectsAllowed(boolean circularRedirectsAllowed) {
        config.setCircularRedirectsAllowed(circularRedirectsAllowed);
        return this;
    }
    
    /**
     * 设置是否启用调转
     * @author mdc
     * @date 2015年7月18日
     * @param redirectsEnabled
     * @return
     */
    public HttpUtils setRedirectsEnabled(boolean redirectsEnabled) {
        config.setRedirectsEnabled(redirectsEnabled);
        return this;
    }
    
    /**
     * 设置重定向的次数
     * @author mdc
     * @date 2015年7月18日
     * @param maxRedirects
     * @return
     */
    public HttpUtils maxRedirects(int maxRedirects){
        config.setMaxRedirects(maxRedirects);
        return this;
    }
    
    /**
     * 执行请求
     * @author mdc
     * @date 2015年7月17日
     * @return
     */
    public ResponseWrap execute() {
        settingRequest();
        if(httpClient == null) {
            httpClient = clientBuilder.build();
        }
        
        try {
            HttpClientContext context = HttpClientContext.create();
            CloseableHttpResponse response = httpClient.execute(request, context);
            return new ResponseWrap(httpClient, request, response, context, mapper);
        } catch (IOException e) {
            logger.error(e.getMessage(), e);
            throw new RuntimeException(e.getMessage(), e);
        }
    }

    /**
     * 执行请求
     * @author mdc
     * @date 2015年7月17日
     * @param responseHandler
     * @return
     */
    public <T> T execute(final ResponseHandler<? extends T> responseHandler) {
        settingRequest();
        if(httpClient == null) httpClient = clientBuilder.build();
        
        try {
            return httpClient.execute(request, responseHandler);
        } catch (IOException e) {
            logger.error(e.getMessage(), e);
            throw new RuntimeException(e.getMessage(), e);
        }
    }
    

    /**
     * 关闭连接
     * @author mdc
     * @date 2015年7月18日
     */
    @SuppressWarnings("deprecation")
    public void shutdown(){
        httpClient.getConnectionManager().shutdown();
    }
    
    /**
     * 获取LayeredConnectionSocketFactory 使用ssl单向认证
     * @author mdc
     * @date 2015年7月17日
     * @return
     */
    private LayeredConnectionSocketFactory getSSLSocketFactory() {
        try {
            SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
                // 信任所有
                public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                    return true;
                }
            }).build();

            SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
            return sslsf;
        } catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException e) {
            logger.error(e.getMessage(), e);
            throw new RuntimeException(e.getMessage(), e);
        }
    }
    
    private void settingRequest() {
        URI uri = null;
        if(uriBuilder != null) {
            try {
                uri = uriBuilder.setPath(request.getURI().toString()).build();
            } catch (URISyntaxException e) {
                logger.warn(e.getMessage(), e);
            }
        }
        
        HttpEntity httpEntity = null;
        
        switch (type) {
        case 1:
            httpEntity = builder.build();
            if(httpEntity.getContentLength() > 0) ((HttpPost)request).setEntity(builder.build());
            break;
            
        case 2:
            HttpGet get = ((HttpGet)request);
            get.setURI(uri);
            break;
        
        case 3:
            httpEntity = builder.build();
            if(httpEntity.getContentLength() > 0) ((HttpPut)request).setEntity(httpEntity);
            break;
            
        case 4:
            HttpDelete delete = ((HttpDelete)request);
            delete.setURI(uri);
            break;
        }
        
        if (isHttps && socketFactory != null ) {
            clientBuilder.setSSLSocketFactory(socketFactory);
        
        } else if(isHttps) {
            clientBuilder.setSSLSocketFactory(getSSLSocketFactory());
        }
        
        clientBuilder.setDefaultCookieStore(cookieStore);
        request.setConfig(config.build());
    }
    
    

    //json转换器
    private static ObjectMapper mapper = new ObjectMapper();
    static{
        mapper.setSerializationInclusion(Include.NON_DEFAULT);
        // 设置输入时忽略在JSON字符串中存在但Java对象实际没有的属性
        mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
        mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
        mapper.enable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT);
        mapper.getFactory().enable(Feature.ALLOW_COMMENTS);
        mapper.getFactory().enable(Feature.ALLOW_SINGLE_QUOTES);
    }
}

ResponseWrap类,用来对响应结果的处理

import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.URI;
import java.nio.charset.Charset;
import java.util.List;

import org.apache.http.Consts;
import org.apache.http.Header;
import org.apache.http.HeaderIterator;
import org.apache.http.HttpEntity;
import org.apache.http.ParseException;
import org.apache.http.ProtocolVersion;
import org.apache.http.StatusLine;
import org.apache.http.client.CookieStore;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.cookie.Cookie;
import org.apache.http.entity.BasicHttpEntity;
import org.apache.http.entity.BufferedHttpEntity;
import org.apache.http.entity.ContentType;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.message.BasicHeader;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;

/**
 * @author mdc
 * @date 2015年7月17日
 */
public class ResponseWrap {
    private Logger logger = LoggerFactory.getLogger(ResponseWrap.class);
    
    private CloseableHttpResponse response;
    private CloseableHttpClient httpClient;
    private HttpEntity entity;
    private HttpRequestBase request;
    private HttpClientContext context;
    private static ObjectMapper mapper;
    
    public ResponseWrap(CloseableHttpClient httpClient, HttpRequestBase request, CloseableHttpResponse response, HttpClientContext context, ObjectMapper _mapper){
        this.response = response;
        this.httpClient = httpClient;
        this.request = request;
        this.context = context;
        mapper = _mapper;
        
        try {
            HttpEntity entity = response.getEntity();
            if(entity != null) {
                this.entity =  new BufferedHttpEntity(entity);
            } else {
                this.entity = new BasicHttpEntity();
            }
            
            EntityUtils.consumeQuietly(entity);
            this.response.close();
        } catch (IOException e) {
            logger.warn(e.getMessage());
        }
    }
    

    /**
     * 终止请求
     * @author mdc
     * @date 2015年7月18日
     */
    public void abort(){
        request.abort();
    }
    
    /**
     * 获取重定向的地址
     * @author mdc
     * @date 2015年7月18日
     * @return
     */
    public List<URI> getRedirectLocations(){
        return context.getRedirectLocations();
    }
    
    /**
     * 关闭连接
     * @author mdc
     * @date 2015年7月18日
     */
    @SuppressWarnings("deprecation")
    public void shutdown(){
        httpClient.getConnectionManager().shutdown();
    }
    
    /**
     * 获取响应内容为String,默认编码为 "UTF-8"
     * @author mdc
     * @date 2015年7月17日
     * @return
     */
    public String getString() {
        return getString(Consts.UTF_8);
    }
    
    /**
     * 获取响应内容为String
     * @author mdc
     * @date 2015年7月17日
     * @param defaultCharset 指定编码
     * @return
     */
    public String getString(Charset defaultCharset) {
        try {
            return EntityUtils.toString(entity, defaultCharset);
        } catch (ParseException | IOException e) {
            logger.error(e.getMessage(), e);
            throw new RuntimeException(e.getMessage(), e);
        }
    }
    
    /**
     * 获取响应的类型
     * @author mdc
     * @date 2015年7月18日
     * @return
     */
    public Header getContentType() {
        return entity.getContentType();
    }
    
    /**
     * 获取响应编码,如果是文本的话
     * @author mdc
     * @date 2015年7月18日
     * @return
     */
    public Charset getCharset() {
         ContentType contentType = ContentType.get(entity);
         if(contentType == null) return null;
         return contentType.getCharset();
    }
    
    /**
     * 获取响应内容为字节数组
     * @author mdc
     * @date 2015年7月17日
     * @return
     */
    public byte[] getByteArray() {
        try {
            return EntityUtils.toByteArray(entity);
        } catch (ParseException | IOException e) {
            logger.error(e.getMessage(), e);
            throw new RuntimeException(e.getMessage(), e);
        }
    }
    
    /**
     * 获取所有Header
     * @author mdc
     * @date 2015年7月17日
     * @return
     */
    public Header[] getAllHeaders() {
        return response.getAllHeaders();
    }
    
    /**
     * 获取知道名称的Header列表
     * @author mdc
     * @date 2015年7月17日
     * @return
     */
    public Header[] getHeaders(String name) {
        return response.getHeaders(name);
    }
    
    /**
     * 获取响应状态信息
     * @author mdc
     * @date 2015年7月17日
     * @return
     */
    public StatusLine getStatusLine(){
        return response.getStatusLine();
    }
    
    /**
     * 移除指定name的Header列表
     * @author mdc
     * @date 2015年7月17日
     * @param name
     */
    public void removeHeaders(String name){
        response.removeHeaders(name);
    }
    
    /**
     * 移除指定的Header
     * @author mdc
     * @date 2015年7月17日
     * @param header
     */
    public void removeHeader(Header header){
        response.removeHeader(header);
    }
    
    /**
     * 移除指定的Header
     * @author mdc
     * @date 2015年7月17日
     * @param name
     * @param value
     */
    public void removeHeader(String name, String value){
        response.removeHeader(new BasicHeader(name, value));
    }
    
    /**
     * 是否存在指定name的Header
     * @author mdc
     * @date 2015年7月17日
     * @param name
     * @return
     */
    public boolean containsHeader(String name){
        return response.containsHeader(name);
    }
    
    /**
     * 获取Header的迭代器
     * @author mdc
     * @date 2015年7月17日
     * @return
     */
    public HeaderIterator headerIterator(){
        return response.headerIterator();
    }

    /**
     * 获取协议版本信息
     * @author mdc
     * @date 2015年7月17日
     * @return
     */
    public ProtocolVersion getProtocolVersion(){
        return response.getProtocolVersion();
    }
    
    /**
     * 获取CookieStore
     * @author mdc
     * @date 2015年7月18日
     * @return
     */
    public CookieStore getCookieStore(){
        return context.getCookieStore();
    }
    
    /**
     * 获取Cookie列表
     * @author mdc
     * @date 2015年7月18日
     * @return
     */
    public List<Cookie> getCookies(){
        return getCookieStore().getCookies();
    }
    
    /**
     * 获取InputStream,需要手动关闭流
     * @author mdc
     * @date 2015年7月17日
     * @return
     */
    public InputStream getInputStream(){
        try {
            return entity.getContent();
        } catch (IllegalStateException | IOException e) {
            logger.error(e.getMessage(), e);
            throw new RuntimeException(e.getMessage(), e);
        }
    }
    
    /**
     * 获取BufferedReader
     * @author mdc
     * @date 2015年7月18日
     * @return
     */
    public BufferedReader getBufferedReader(){
        return new BufferedReader(new InputStreamReader(getInputStream(), getCharset()));
    }
    
    /**
     * 响应内容写入到文件
     * @author mdc
     * @date 2015年7月17日
     * @param filePth 路径
     */
    public void transferTo(String filePth) {
        transferTo(new File(filePth));
    }
    
    /**
     * 响应内容写入到文件
     * @author mdc
     * @date 2015年7月17日
     * @param file
     */
    public void transferTo(File file) {
        try(FileOutputStream fileOutputStream = new FileOutputStream(file)){
            transferTo(fileOutputStream);
        }catch (Exception e) {
            throw new RuntimeException(e.getMessage(), e);
        }
    }
    
    /**
     * 写入到OutputStream,并不会关闭OutputStream
     * @author mdc
     * @date 2015年7月17日
     * @param outputStream OutputStream
     */
    public void transferTo(OutputStream outputStream) {
        try {
            entity.writeTo(outputStream);
        } catch (Exception e) {
            logger.warn(e.getMessage(), e);
            throw new RuntimeException(e.getMessage(), e);
        }
    }
    
    /**
     * 获取JSON对象
     * @author mdc
     * @date 2015年7月24日
     * @param clazz
     * @return
     */
    public <T> T getJson(Class<T> clazz) {
        try {
            return mapper.readValue(getByteArray(), clazz);
        } catch (IOException e) {
            logger.warn(e.getMessage(), e);
            throw new RuntimeException(e.getMessage(), e);
        }
    }

    /**
     * 把Json转换成List
     * @author mdc
     * @date 2015年7月24日
     * @param clazz
     * @return
     */
    public <T> List<T> getJsonList(Class<?> clazz) {
        try {
            return mapper.readValue(getByteArray(), new TypeReference<List<T>>() {});
        } catch (IOException e) {
            logger.warn(e.getMessage(), e);
            throw new RuntimeException(e.getMessage(), e);
        }
    }
    
}

说明:

  1. https单向认证,会自动去除域名校验。双向认证需要在执行execute之前需要设置证书调用setJks方法
  2. Session保持有两种实现方式
  • 获取响应后的ResponseWrap CookieStore设置到新的请求CookieStore
  • 在新的请求里设置上一次请求的HttpUtils的实例,推荐使用这种,因为效率高

下面是测试代码

请求百度搜索“java 核心技术”

String url = "http://www.baidu.com/s";
HttpUtils http = HttpUtils.get(url);
http.addParameter("wd", "java 核心技术"); //搜索关键字
http.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:39.0) Gecko/20100101 Firefox/39.0");
http.setProxy("10.10.12.62", 3128); //设置代理
ResponseWrap response = http.execute(); //执行请求
System.out.println(response.getString()); //输出内容
response.transferTo("d:/baidu-search-java.html"); //输出到文件
http.shutdown();
时间: 2024-10-17 15:33:16

基于apache-httpclient 4.3封装的HttpUtils的相关文章

基于apache —HttpClient的小爬虫获取网页内容

今天(17-03-31)忙了一下午研究webmagic,发现自己还太年轻,对于这样难度的框架(类库) 还是难以接受,还是从基础开始吧,因为相对基础的东西教程相多一些,于是乎我找了apache其下的 HttpClient,根据前辈们发的教程自己也简单写了一下,感觉还好. 下面实现的是单个页面的获取: import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.clien

android使用apache httpclient发送post请求

package com.liuc; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.List; import java.util.Map; import org.apache.ht

Apache HttpClient

HpptClient特性 1. 基于标准.纯净的java语言.实现了Http1.0和Http1.1 2. 以可扩展的面向对象的结构实现了Http全部的方法(GET, POST, PUT, DELETE, HEAD, OPTIONS, and TRACE). 3. 支持HTTPS协议. 4. 通过Http代理建立透明的连接. 5. 利用CONNECT方法通过Http代理建立隧道的https连接. 6. Basic, Digest, NTLMv1, NTLMv2, NTLM2 Session, SN

基于表单数据的封装,泛型,反射以及使用BeanUtils进行处理

在Java Web开发过程中,会遇到很多的表单数据的提交和对表单数据的处理.而每次都需要对这些数据的字段进行一个一个的处理就显得尤为繁琐,在Java语言中,面向对象的存在目的便是为了消除重复代码,减少我们程序员的负担.因此,在这里和大家分享一下我学到的一个小技巧. 对于封装 这里说的"封装",是指将从客户端提交的表单数据封装到一个bean层entitry中.这样可以方便对数据的处理.下面就来看一个具体的bean实例化的小例子吧. 比如说我们从网页上获得用户的登录信息,一般来说是用户名和

Apache HttpClient : Http Cookies

前言 HttpClient已经被集成到Android的SDK里,但在JDK里面仍然需要HttpURLConnectionn发起HTTP请求.HttpClient可以看做是一个加强版的HttpURLConnection,但它的侧重点是如何发送请求.接受相应和管理Http连接. 在介绍Http Cookies之前,笔者给出一个应用场景:你需要一个根据地理信息(城市名或者经纬度)获取天气的应用.可选的API很多,不幸的是,网上提到的Google天气API已经停止服务了(不是被墙):雅虎是英文的,且需要

基于Apache+Tomcat负载均衡的两种实现方法

Apache+Tomcat实现负载均衡的两种实现方法 如果我们将工作在不同平台的apache能够实现彼此间的高效通信,因此它需要一种底层机制来实现--叫做apr Apr的主要目的就是为了其能够让apache工作在不同的平台上,但在linux上安装apache的时候通常都是默认安装的 [[email protected] ~]#rpm -qi aprName                 :apr                                        Relocation

基于sqlite的Qt 数据库封装

[代码] mydata.h 10 #ifndef MYDATA_H 11 #define MYDATA_H 12 #include <QObject> 13 #include <QString> 14 #include <QtSql/QSqlTableModel> 15 #include <QtSql/QSqlQuery> 16 #include <QStringList> 17 #include <QtSql/QSqlDatabase&g

Tomcat:基于Apache+Tomcat的集群搭建

根据Tomcat的官方文档说明可以知道,使用Tomcat配置集群需要与其它Web Server配合使用才可以完成,典型的有Apache和IIS. 这里就使用Apache+Tomcat方式来完成基于Tomcat在集群配置. 软件准备 1)Apache HTTP Server: 使用百度搜索httpd-2.2.25-win32-x86-no_ssl.msi,应该可以找到很多相关的下载链接.这里也提供一个:http://vdisk.weibo.com/s/C3trk_uGGkrmc 2)Tomcat

c#编写的基于Socket的异步通信系统封装DLL--SanNiuSignal.DLL

SanNiuSignal是一个基于异步socket的完全免费DLL:它里面封装了Client,Server以及UDP:有了这个DLL:用户不用去关心心跳:粘包 :组包:发送文件等繁琐的事情:大家只要简单的几步就能实现强大的通信系统:能帮助到大家是本人觉得最幸福的事情,也希望大家 在用的过程中找出DLL中不足的地方:好改正:此DLL的苹果版和java版正在努力开发中......交流QQ:365368248:此演示源码下载地址:http://pan.baidu.com/s/1eQw1npw 里面包括

基于Apache mina 的android 客户端tcp长连接实现

TCP-long-connection-based-on-Apache-mina 基于Apache mina 的tcp长连接实现,可用于android客户端推送. 项目Github地址:https://github.com/sddyljsx/Android-tcp-long-connection-based-on-Apache-mina 项目将Apache的mina项目移植到了android平台.实现长连接的主要思想是使用了mina的KeepAliveFilter过滤器. acceptor.ge