Java HttpClient偽造請求之簡易封裝滿足HTTP以及HTTPS請求


HttpClient簡介

HTTP 協議可能是現在 Internet 上使用得最多、最重要的協議了,越來越多的 Java 應用程序需要直接通過 HTTP 協議來訪問網絡資源。雖然在 JDK 的 java.net 包中已經提供了訪問 HTTP 協議的基本功能,但是對於大部分應用程序來說,JDK 庫本身提供的功能還不夠豐富和靈活。HttpClient 是 Apache Jakarta Common 下的子項目,用來提供高效的、最新的、功能豐富的支持 HTTP 協議的客戶端編程工具包,並且它支持 HTTP 協議最新的版本和建議。HttpClient 已經應用在很多的項目中,比如 Apache Jakarta 上很著名的另外兩個開源項目 Cactus 和 HTMLUnit 都使用了 HttpClient。更多信息請關注http://hc.apache.org/

HttpClient 功能介紹

以下列出的是 HttpClient 提供的主要的功能,要知道更多詳細的功能可以參見 HttpClient 的主頁。

  • 實現了所有 HTTP 的方法(GET,POST,PUT,HEAD 等)

  • 支持自動轉向

  • 支持 HTTPS 協議

  • 支持代理服務器等

為什么使用此封裝類?

不少的朋友使用了org.apache.http.client.methods.HttpGet和org.apache.http.client.methods.HttpPost這兩個封裝類進行抓取網頁數據,偽造提交。當然本封裝類也是基於這兩個類進行再次封裝的。使用過這兩個類的朋友應該發現一些問題就是,每寫一個偽造請求都需要實例一個對象。然而還無法很好的管理線程池的問題。導致幾個請求一起觸發的時候就會出現一直無響應,直到出現timeout。還要單獨管理線程池的溢出和每一個請求的超時。所以這就是本類封裝的緣故。當然這個封裝類封裝是傻瓜式的。只是解決了部分繁瑣的代碼,簡便了一些重復的操作。同時自動管理了線程池的問題以及HTTPS證書問題。封裝后最大的效果就是抽象,簡便重復操作。使用此類完整的獲取一個HTML頁面內容只需要兩行代碼即可:

 HttpClient client = new HttpClient("http://www.sohu.com/picture/209151068?_f=index_news_25");
            System.out.println(client.request());

  

基於org.apache.httpcomponents -4.5.1  版本的HttpClient 做封裝

項目中引用的話記得在maven中添加對應的pom:

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

  

1、新建擴展類 “StringUtil”

    public static class StringUtil {

        /**
         * 判斷字符串是否為空
         *
         * @param value
         * @return
         */
        public static boolean isEmpty(String value) {
            return value == null || "".equals(value.trim());
        }

        /**
         * 判斷字符串是否不為空
         *
         * @param str
         * @return
         */
        public static boolean isNotEmpty(String str) {
            return !isEmpty(str);
        }

        /**
         * 判斷是否是數字
         *
         * @param sourceString
         * @return
         */
        public static boolean isNumber(String sourceString) {
            if (isEmpty(sourceString))
                return false;
            char[] sourceChar = sourceString.toCharArray();
            for (int i = 0; i < sourceChar.length; i++)
                if ((sourceChar[i] < '0') || (sourceChar[i] > '9'))
                    return false;
            return true;
        }
    }

  2、新建擴展hashMap “CommonMap”

import java.util.HashMap;

/**
 * 擴展hashMap
 * Created by Administrator on 2015/6/8.
 */
public class CommonMap<K,V> extends HashMap<K,V>{

    public CommonMap(){}
    public CommonMap(K key, V value){
        this.put(key,value);
    }
    public CommonMap<K,V> add(K key,V value){
        this.put(key,value);
        return this;
    }
    public CommonMap<K,V> delete(K key){
        this.remove(key);
        return this;
    }
}

3、新建SSL類“MySSLProtocolSocketFactory”

import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.UnknownHostException;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.SocketFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import org.apache.commons.httpclient.ConnectTimeoutException;
import org.apache.commons.httpclient.params.HttpConnectionParams;
import org.apache.commons.httpclient.protocol.ProtocolSocketFactory;



/**
 * author by zhangwei
 *
 * created at 2010-7-26 上午09:29:33 
 */
public class MySSLProtocolSocketFactory implements ProtocolSocketFactory {
    private SSLContext sslcontext = null;

    private SSLContext createSSLContext() {
        SSLContext sslcontext=null;
        try {
            sslcontext = SSLContext.getInstance("SSL");
            sslcontext.init(null, new TrustManager[]{new TrustAnyTrustManager()}, new java.security.SecureRandom());
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (KeyManagementException e) {
            e.printStackTrace();
        }
        return sslcontext;
    }

    private SSLContext getSSLContext() {
        if (this.sslcontext == null) {
            this.sslcontext = createSSLContext();
        }
        return this.sslcontext;
    }

    public Socket createSocket(Socket socket, String host, int port, boolean autoClose)
            throws IOException, UnknownHostException {
        return getSSLContext().getSocketFactory().createSocket(
                socket,
                host,
                port,
                autoClose
        );
    }

    public Socket createSocket(String host, int port) throws IOException,
            UnknownHostException {
        return getSSLContext().getSocketFactory().createSocket(
                host,
                port
        );
    }


    public Socket createSocket(String host, int port, InetAddress clientHost, int clientPort)
            throws IOException, UnknownHostException {
        return getSSLContext().getSocketFactory().createSocket(host, port, clientHost, clientPort);
    }

    public Socket createSocket(String host, int port, InetAddress localAddress,
                               int localPort, HttpConnectionParams params) throws IOException,
            UnknownHostException, ConnectTimeoutException {
        if (params == null) {
            throw new IllegalArgumentException("Parameters may not be null");
        }
        int timeout = params.getConnectionTimeout();
        SocketFactory socketfactory = getSSLContext().getSocketFactory();
        if (timeout == 0) {
            return socketfactory.createSocket(host, port, localAddress, localPort);
        } else {
            Socket socket = socketfactory.createSocket();
            SocketAddress localaddr = new InetSocketAddress(localAddress, localPort);
            SocketAddress remoteaddr = new InetSocketAddress(host, port);
            socket.bind(localaddr);
            socket.connect(remoteaddr, timeout);
            return socket;
        }
    }

    //自定義私有類
    private static class TrustAnyTrustManager implements X509TrustManager {

        public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
        }

        public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
        }

        public X509Certificate[] getAcceptedIssuers() {
            return new X509Certificate[]{};
        }
    }


}  

4、新建HttpClient 請求核心封裝類 “HttpClient ”

import CommonMap;
import MySSLProtocolSocketFactory;
import org.apache.commons.httpclient.protocol.Protocol;
import org.apache.http.*;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.AuthCache;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.config.RequestConfig;
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.protocol.HttpClientContext;
import org.apache.http.client.utils.HttpClientUtils;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.auth.BasicScheme;
import org.apache.http.impl.client.BasicAuthCache;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.io.*;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Created by zhangwei on 2017/9/5.
 * httpClient
 */
public class HttpClient {
    /**
     * 請求類型  get/post
     */
    public String METHOD_NAME = "GET";
    /**
     * 請求的地址 url
     */
    private String URL = "";
    /**
     * HttpHost 代理對象
     */
    private HttpHost httpHost = null;
    /**
     * HTTP身份認證 用戶憑證
     */
    private CredentialsProvider credsProvider = null;
    /**
     * clinet上下文對象
     * 用來應用程序經常需要通過一些邏輯相關的請求-響應交換來保持狀態信息。
     * 為了使應用程序能夠維持一個過程狀態,
     * HttpClient允許HTTP請求在一個特定的執行上下文中來執行--稱為HTTP上下文
     */
    private HttpClientContext httpClientContext = null;
    /**
     * httpclient的請求對象  線程池
     */
    private CloseableHttpClient httpclient = null;
    /**
     * 用回來獲取請求響應的對象
     */
    private CloseableHttpResponse closeableHttpResponse = null;
    /**
     * get請求對象
     */
    private HttpGet httpGet = null;
    /**
     * post請求對象
     */
    private HttpPost httpPost = null;
    /**
     * 服務器響應超時 單位毫秒
     */
    private int socketTimeout = 20000;
    /**
     * 連接被阻塞超時 單位毫秒
     */
    private int connectTimeout = 20000;
    /**
     * 請求超時的時間 單位毫秒
     */
    private int connectionRequestTimeout = 20000;
    /**
     * 最大不要超過1000
     */
    private static int maxConnTotal = 10;
    /**
     * 實際的單個連接池大小,如tps定為50,那就配置50
     */
    private static int maxConnPerRoute = 20;
    private String accept = "*/*";
    private String referer = "";
    private String contentType = "";
    private String origin = "";
    private String userAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36";
    private boolean autoSaveReferer;

    /**
     * 自動保存上一個請求源 true 自動保存/false 不自動保存(默認)
     */
    public void setAutoSaveReferer(boolean autoSaveReferer) {
        this.autoSaveReferer = autoSaveReferer;
    }

    /**
     * 先前網頁的地址
     */
    public void setReferer(String referer) {
        this.referer = referer;
    }

    /**
     * 客戶端能夠接收的內容類型
     */
    public void setAccept(String accept) {
        this.accept = accept;
    }

    /**
     * 請求的與實體對應的MIME信息
     */
    public void setContentType(String contentType) {
        this.contentType = contentType;
    }

    /**
     * 請求的來源-post使用,等同於Referer頭
     */
    public void setOrigin(String origin) {
        this.origin = origin;
    }

    /**
     * 注明客戶端請求的觸發器版本
     *
     * @param userAgent
     */
    public void setUserAgent(String userAgent) {
        this.userAgent = userAgent;
    }

    /**
     * 服務器響應超時 單位毫秒
     *
     * @param socketTimeout
     */
    public void setSocketTimeout(int socketTimeout) {
        this.socketTimeout = socketTimeout;
    }


    /**
     * 連接被阻塞超時 單位毫秒
     *
     * @param connectTimeout
     */
    public void setConnectTimeout(int connectTimeout) {
        this.connectTimeout = connectTimeout;
    }

    /**
     * 請求超時的時間 單位毫秒
     *
     * @param connectionRequestTimeout
     */
    public void setConnectionRequestTimeout(int connectionRequestTimeout) {
        this.connectionRequestTimeout = connectionRequestTimeout;
    }


    /**
     * 最大的請求連接數 注意:最大不要超過1000
     *
     * @param maxConnTotal
     */
    public static void setMaxConnTotal(int maxConnTotal) {
        HttpClient.maxConnTotal = maxConnTotal;
    }


    /**
     * 實際的單個連接池大小,如tps定為50,那就配置50
     *
     * @param maxConnPerRoute
     */
    public static void setMaxConnPerRoute(int maxConnPerRoute) {
        HttpClient.maxConnPerRoute = maxConnPerRoute;
    }

    private boolean isAutoSaveReferer() {
        return autoSaveReferer;
    }


    /**
     * 構造函數 無參
     */
    public HttpClient() {
        initHttpRequest();
    }

    /**
     * 構造函數 初始化包含UR
     *
     * @param URL
     */
    public HttpClient(String URL) {
        this.URL = URL;
        initHttpRequest();
    }

    /**
     * 構造函數 初始化包含URL和請求類型
     *
     * @param URL
     * @param METHOD_NAME
     */
    public HttpClient(String URL, String METHOD_NAME) {
        this.URL = URL;
        this.METHOD_NAME = METHOD_NAME;
        initHttpRequest();
    }

    /**
     * 初始化htpclinet的請求對象
     */
    public void initHttpRequest() {
        if (METHOD_NAME.equalsIgnoreCase("get")) {
            if (httpGet == null) {
                if (StringUtil.isNotEmpty(URL)) {
                    httpGet = new HttpGet(URL);
                } else {
                    httpGet = new HttpGet();
                }
            } else {
                try {
                    httpGet.setURI(new java.net.URI(URL));
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            httpGet.setHeader("Accept", accept);
            httpGet.setHeader("User-Agent", userAgent);
            if (StringUtil.isNotEmpty(contentType)) {
                httpGet.setHeader("Content-Type", contentType);
            }
            if (StringUtil.isNotEmpty(referer)) {
                httpGet.setHeader("Referer", referer);
            }
        } else if (METHOD_NAME.equalsIgnoreCase("post")) {
            if (httpPost == null) {
                if (StringUtil.isNotEmpty(URL)) {
                    httpPost = new HttpPost(URL);
                } else {
                    httpPost = new HttpPost();
                }
            } else {
                try {
                    httpPost.setURI(new java.net.URI(URL));
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            httpPost.setHeader("Accept", accept);
            if (StringUtil.isNotEmpty(contentType)) {
                httpPost.setHeader("Content-Type", contentType);
            }
            httpPost.setHeader("Origin", origin);
            httpPost.setHeader("User-Agent", userAgent);
            if (StringUtil.isNotEmpty(referer)) {
                httpPost.setHeader("Referer", referer);
            }
        }
        initHttpClinet();
    }

    /**
     * 設置提交方式 get/post
     *
     * @param method
     * @throws Exception
     */
    public void setMethod(String method) throws Exception {
        try {
            if (StringUtil.isNotEmpty(method)) {
                METHOD_NAME = method;
                initHttpRequest();
            } else {
                throw new Exception("參數不能為空,method is null");
            }
        } catch (Exception e) {
            throw new Exception(e.getMessage());
        }
    }

    /**
     * 關閉client連接對象 釋放對象 並重新初始化
     *
     * @throws Exception
     */
    public void closeClient(boolean isInit) {
        if (httpclient != null) {
            try {
                // 關閉請求
                httpclient.getConnectionManager().shutdown();
                HttpClientUtils.closeQuietly(httpclient);
                httpclient = null;
                if (closeableHttpResponse != null) {
                    closeableHttpResponse.close();//防止線程池一直占用,無法釋放內存,導致后面的請求響應堵塞
                }
                if (httpGet != null) {
                    httpGet = null;
                }
                if (httpPost != null) {
                    httpPost = null;
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (isInit) {//如果是異常關的httpclient對象一定要重新初始化對象,以免訪問出現空指針
                    initHttpClinet();
                }
            }
        }
    }

    /**
     * 初始化clinet請求對象-並初始化HTTP/HTTPS兩種協議
     */
    public void initHttpClinet() {
        if (httpclient == null) {
            try {
                System.setProperty("jsse.enableSNIExtension", "false");
                //采用繞過驗證的方式處理https請求
                SSLContext sslcontext = createIgnoreVerifySSL();
                // 設置協議http和https對應的處理socket鏈接工廠的對象
                Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
                        .register("http", PlainConnectionSocketFactory.INSTANCE)
                        .register("https", new SSLConnectionSocketFactory(sslcontext))
                        .build();
                Protocol myhttps = new Protocol("https", new MySSLProtocolSocketFactory(), 443);
                Protocol.registerProtocol("https", myhttps);
                PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
                RequestConfig defaultRequestConfig = RequestConfig.custom()
                        .setSocketTimeout(socketTimeout)
                        .setConnectTimeout(connectTimeout)
                        .setConnectionRequestTimeout(connectionRequestTimeout)
                        .setStaleConnectionCheckEnabled(true)
                        .build();

                httpclient = HttpClients.custom()
                        .setDefaultRequestConfig(defaultRequestConfig).setMaxConnTotal(maxConnTotal)
                        .setMaxConnPerRoute(maxConnPerRoute).setConnectionManager(connManager)
                        .build();
               /* .setSSLSocketFactory(new SSLConnectionSocketFactory(sslcontext))*/
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 請求數據並返回字符串類型
     *
     * @return
     * @throws Exception
     */
    public String request() throws Exception {
        try {
            HttpEntity entity = request(URL);
            InputStream inputStream = entity.getContent();
            if (inputStream != null) {
                return readLineInputStream("utf-8", inputStream);
            } else {
                return "";
            }
        } catch (Exception e) {
            throw new Exception(msgException(e));
        } finally {
            closeHttpResponse();
        }
    }

    /**
     * 請求數據並返回一個數據實體
     *
     * @param url
     * @return
     * @throws Exception
     */
    public HttpEntity request(String url) throws Exception {
        try {
            if (StringUtil.isNotEmpty(url)) {
                URL = url;
            } else {
                throw new Exception("參數不能為空,url is null");
            }
            if (StringUtil.isEmpty(origin)) {
                origin = URL;
            }
            initHttpRequest();
            if (httpHost != null) {
                closeableHttpResponse = httpclient.execute(httpHost, METHOD_NAME.equalsIgnoreCase("get") ? httpGet : httpPost);
            } else if (httpHost != null && httpClientContext != null) {
                closeableHttpResponse = httpclient.execute(httpHost, METHOD_NAME.equalsIgnoreCase("get") ? httpGet : httpPost, httpClientContext);
            } else {
                closeableHttpResponse = httpclient.execute(METHOD_NAME.equalsIgnoreCase("get") ? httpGet : httpPost);
            }
            if (isAutoSaveReferer()) {
                setReferer(URL);
            }
            return closeableHttpResponse.getEntity();
        } catch (Exception e) {
            closeClient(true); //如果出現異常了就進行請求釋放,防止異常未捕獲導致回收失敗
            throw new Exception(msgException(e));
        } finally {
            if (httpPost != null)
                httpPost.setEntity(null);
        }
    }


    /**
     * 請求數據並返回數據 自定義流轉文本編碼格式
     *
     * @param url
     * @param utf
     * @return
     * @throws Exception
     */
    public String request(String url, String utf) throws Exception {
        try {
            utf = StringUtil.isEmpty(utf) ? "utf-8" : utf;
            HttpEntity entity = request(url);
            InputStream inputStream = entity.getContent();
            if (inputStream != null) {
                return readLineInputStream(utf, inputStream);
            } else {
                return "";
            }
        } catch (Exception e) {
            throw new Exception(msgException(e));
        } finally {
            closeHttpResponse();
        }
    }

    /**
     * 請求並返回byte數組數據
     *
     * @param url
     * @param numBer
     * @return
     * @throws Exception
     */
    public byte[] request(String url, Integer numBer) throws Exception {
        try {
            return toByteArrays(request(url).getContent(), numBer);
        } catch (EOFException e) {
            throw new Exception(e.getMessage());
        } finally {
            closeHttpResponse();
        }
    }

    /**
     * 文件流轉byte數組
     *
     * @param in
     * @param numBer
     * @return
     * @throws Exception
     */
    public byte[] toByteArrays(InputStream in, Integer numBer) throws Exception {
        numBer = numBer == null ? 8 : numBer;
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024 * numBer];
        int i = 0;
        while ((i = in.read(buffer)) != -1) {
            out.write(buffer, 0, i);
        }
        return out.toByteArray();
    }

    /**
     * 重載讀取流
     *
     * @param utf
     * @param httpEntity
     * @return
     * @throws IOException
     */
    public String readLineInputStream(String utf, HttpEntity httpEntity) throws IOException {
        return readLineInputStream(utf, httpEntity.getContent());
    }

    /**
     * 重載讀取流
     *
     * @param utf
     * @param inputStream
     * @return
     * @throws IOException
     */
    public String readLineInputStream(String utf, InputStream inputStream) throws IOException {
        BufferedReader bf = null;
        InputStreamReader isr = null;
        try {
            isr = new InputStreamReader(inputStream,
                    utf);
            bf = new BufferedReader(isr);
            StringBuffer buffer = new StringBuffer();
            String line = "";
            while ((line = bf.readLine()) != null) {
                buffer.append(line);
            }
            return buffer.toString();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            bf.close();
            isr.close();
            inputStream.close();
        }
        return "";
    }

    /**
     * 重載讀取流
     *
     * @param inputStream
     * @return
     * @throws IOException
     */
    public String readLineInputStream(InputStream inputStream) throws IOException {
        return readLineInputStream("utf-8", inputStream);
    }

    /**
     * 重載讀取流
     *
     * @param httpEntity
     * @return
     * @throws IOException
     */
    public String readLineInputStream(HttpEntity httpEntity) throws Exception {
        try {
            if (httpEntity != null) {
                return readLineInputStream("utf-8", httpEntity.getContent());
            } else {
                return "";
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new Exception("讀取文件流異常:" + e.getMessage());
        }
    }

    /**
     * 設置cookie
     *
     * @param cookie
     */
    public void setCookie(String cookie) {
        if (METHOD_NAME.equalsIgnoreCase("get")) {
            httpGet.setHeader("Cookie", cookie);
        } else if (METHOD_NAME.equalsIgnoreCase("post")) {
            httpPost.setHeader("Cookie", cookie);
        }
    }

    public void setHeader(String headerName, String headerVal) throws Exception {
        setHeader(new CommonMap<String, String>(headerName, headerVal));
    }

    /**
     * 設置Header
     *
     * @param header
     */
    public void setHeader(Map<String, String> header) throws Exception {
        try {
            if (header != null) {
                for (String hd : header.keySet()) {
                    if (METHOD_NAME.equalsIgnoreCase("get")) {
                        httpGet.setHeader(hd, header.get(hd));
                    } else if (METHOD_NAME.equalsIgnoreCase("post")) {
                        httpPost.setHeader(hd, header.get(hd));
                    }
                }
            }
        } catch (Exception e) {
            throw new Exception("setHeader 異常:" + e.getMessage());
        }
    }

    /**
     * 設置post請求參數 string
     *
     * @param params
     * @throws Exception
     */
    public void setEntity(String params) throws Exception {
        setEntity(getUrlParams(params));
    }

    /**
     * 設置post請求參數 map
     *
     * @param params
     * @throws Exception
     */
    public void setEntity(Map<String, String> params) throws Exception {
        try {
            if (METHOD_NAME.equalsIgnoreCase("post")) {
                httpPost.setEntity(new UrlEncodedFormEntity(
                        getNameValuePairs(params), Consts.UTF_8));
            }
        } catch (Exception e) {
            throw new Exception("setEntity 異常:" + e.getMessage());
        }
    }

    /**
     * 設置post請求參數 map
     *
     * @param json
     * @throws Exception
     */
    public void setEntity(StringEntity json) throws Exception {
        try {
            if (METHOD_NAME.equalsIgnoreCase("post")) {
                httpPost.setEntity(json);

            }
        } catch (Exception e) {
            throw new Exception("setEntity 異常:" + e.getMessage());
        }
    }

    /**
     * 獲取返回值的類型
     *
     * @return
     */
    public Header getContentType() throws Exception {
        if (closeableHttpResponse == null || closeableHttpResponse.getEntity() == null) {
            throw new Exception("java.lang.NullPointerException: closeableHttpResponse 為空,請先初始化對象。");
        }
        return closeableHttpResponse.getEntity().getContentType();
    }

    /**
     * 獲取響應的實體類型 並獲取具體類型:jpeg/html/png/gif......
     *
     * @param isFormat
     * @return
     */
    public String getContentType(boolean isFormat) {
        String contentType = "";
        try {
            if (isFormat) {
                contentType = getContentType().toString();
                if (StringUtil.isNotEmpty(contentType)) {
                    int endIndex = contentType.length();
                    if (contentType.indexOf(";") != -1) {
                        endIndex = contentType.indexOf(";");
                    }
                    contentType = StringUtil.isNotEmpty(contentType) ? contentType.substring(contentType.indexOf("/") + 1, endIndex) : "";
                }
            } else {
                return getContentType().toString();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return contentType;
    }

    /**
     * 獲取返回值的狀態
     * 100	客戶端可以繼續
     * 101	指示服務器正根據 Upgrade 頭切換協議
     * 200	請求正常成功
     * 201	指示請求成功並在服務器上創建了一個新資源
     * 202	指示已接受請求進行處理但處理尚未完成
     * 203	指示客戶端呈現的元信息並不源自服務器
     * 204	指示請求成功但沒有返回新信息
     * 205	指示代理應該 重置導致請求被發送的文檔視圖
     * 206	指示服務器已完成對資源的部分 GET 請求
     * 300	請求的資源對應於表示形式集合中的某種表示形式,每種表示形式都有自己的特定位置
     * 301	指示已經將資源永久地移動到了某個新位置,並且將來的引用應將新 URI 用於其請求
     * 302	指示已經將資源暫時地移動到了另一個位置,但將來的引用仍應使用原來的 URI 訪問該資源。 保留此定義是為了向后兼容。SC_FOUND 現在是首選定義
     * 303	指示可在另一個 URI 之下找到該請求的響應
     * 304	指示條件 GET 操作發現資源可用但不可修改
     * 305	指示必須 通過 Location 字段給定的代理訪問請求資源
     * 307	指示請求的資源暫時駐留在另一個 URI 之下。臨時 URI 應該 通過響應中的 Location 字段提供
     * 400	指示客戶端發送的請求在語法上不正確
     * 401	指示請求需要進行 HTTP 驗證
     * 402	保留此代碼以備將來使用
     * 403	指示服務器理解請求但拒絕完成它
     * 404	指示請求的資源不可用
     * 405	指示 Request-Line 中指定的方法不支持 Request-URI 標識的資源
     * 406	指示請求標識的資源只能生成響應實體,根據請求中發送的 accept 頭,這些響應實體具有不可接受的內容特征
     * 407	指示客戶端必須 首先通過代理驗證其自身
     * 408	指示客戶端沒有在服務器准備等待的時間內生成請求
     * 409	指示由於與當前資源狀態沖突請求無法完成
     * 410	指示資源在服務器上不再可用並且不知道轉發地址。應該 認為此條件是永久性的
     * 411	指示在沒有定義 Content-Length 的情況下無法處理請求
     * 412	指示在服務器上測試一個或多個請求頭字段中給出的前提時,該前提被求值為 false
     * 413	指示因為請求實體大於服務器願意或能夠處理的實體,所以服務器拒絕處理請求
     * 414	指示因為 Request-URI 的長度大於服務器願意解釋的 Request-URI 長度,所以服務器拒絕為請求提供服務
     * 415	指示因為請求實體的格式不受請求方法的請求資源支持,所以服務器拒絕為請求提供服務
     * 416	指示服務器無法服務於請求的字節范圍
     * 417	指示服務器無法服務於請求的字節范圍
     * 500	指示 HTTP 服務器內存在錯誤使服務器無法完成請求
     * 501	指示 HTTP 服務器不支持完成請求所需的功能
     * 502	指示 HTTP 服務器在充當代理或網關時從它參考的服務器接收到一個無效響應
     * 503	指示 HTTP 服務器暫時過載,並且無法處理請求
     * 504	指示服務器在充當網關或代理時沒有從上游服務器接收到及時的響應
     * 505	指示服務器不支持或拒絕支持請求消息中使用的 HTTP 協議版本
     *
     * @return
     */
    public int getStatusCode() throws Exception {
        if (closeableHttpResponse == null || closeableHttpResponse.getStatusLine() == null) {
            throw new Exception("java.lang.NullPointerException: closeableHttpResponse 為空,請先初始化對象。");
        }
        try {
            return closeableHttpResponse.getStatusLine().getStatusCode();
        } catch (Exception e) {
            throw new Exception(e.getMessage());
        }
    }

    public CloseableHttpResponse getHttpResponse() throws Exception {
        try {
            return closeableHttpResponse;
        } catch (Exception e) {
            throw new Exception(e.getMessage());
        }
    }

    /**
     * 關閉線程池,防止堵塞(這里需要手動調用,由於這里吧響應和請求封裝在一個類了所以只能在外面手動調用釋放)
     *
     * @throws IOException
     */
    public void closeHttpResponse() throws IOException {
        if (closeableHttpResponse != null) {
            closeableHttpResponse.close();//防止線程池一直占用,無法釋放內存,導致后面的請求響應堵塞
        }
    }

    /**
     * 關閉線程池,防止堵塞(這里需要手動調用,由於這里吧響應和請求封裝在一個類了所以只能在外面手動調用釋放)
     * 如果出現發送httpclient請求后一直無響應,應該是線程池占用完了,所以每次調用request后記得在finally手動調用本方法CloseHttpResponse
     *
     * @param entity 訪問流結束后需要傳遞實體流進來並釋放掉
     * @throws IOException
     */
    public void closeHttpResponse(HttpEntity entity) throws IOException {
        if (closeableHttpResponse != null) {
            EntityUtils.consume(entity);
            closeableHttpResponse.close();//防止線程池一直占用,無法釋放內存,導致后面的請求響應堵塞
        }
    }

    /**
     * 服務器認證信息
     *
     * @param userName 登錄信息的用戶名
     * @param userPwd  登錄信息的密碼
     * @throws Exception
     */
    public void setCredentials(String userName, String userPwd) throws Exception {
        try {
            if (httpHost == null) {
                throw new Exception("java.lang.NullPointerException: httpHost 為空,請先初始化對象。");
            }
            credsProvider = new BasicCredentialsProvider();
            credsProvider.setCredentials(
                    new AuthScope(httpHost.getHostName(), httpHost.getPort()),
                    new UsernamePasswordCredentials(userName, userPwd));
            // 創建 AuthCache 對象
            AuthCache authCache = new BasicAuthCache();
            //創建 BasicScheme,並把它添加到 auth cache中
            BasicScheme basicAuth = new BasicScheme();
            authCache.put(httpHost, basicAuth);
            // 把AutoCache添加到上下文中
            httpClientContext = HttpClientContext.create();
            httpClientContext.setCredentialsProvider(credsProvider);
            httpClientContext.setAuthCache(authCache);
        } catch (Exception e) {
            throw new Exception(msgException(e));
        }
    }


    /**
     * 設置HTTP請求代理模式
     * 格式:127.0.0.0:8888
     *
     * @param hostVal
     * @throws Exception
     */
    public void setHttpHost(String hostVal) throws Exception {
        if (StringUtil.isNotEmpty(hostVal) && hostVal.indexOf(":") != -1) {
            try {
                String ip = hostVal.substring(0, hostVal.indexOf(":"));
                String host = hostVal.substring(hostVal.indexOf(":") + 1);
                if (StringUtil.isNotEmpty(ip) && isIP(ip) && StringUtil.isNotEmpty(host)) {
                    httpHost = new HttpHost(ip, Integer.parseInt(host));
                }
            } catch (Exception e) {
                throw new Exception(msgException(e));
            }
        } else {
            throw new Exception("httphost 參數內容有誤,正確示范:127.0.1.1:8888");
        }
    }


    /**
     * 通過map對象轉換為數據實體
     *
     * @param params
     * @return
     */
    private static List<NameValuePair> getNameValuePairs(Map<String, String> params) {
        List<NameValuePair> nvps = new ArrayList<NameValuePair>();
        if (params != null && params.keySet().size() > 0) {
            Iterator iterator = params.entrySet().iterator();
            while (iterator.hasNext()) {
                Map.Entry entry = (Map.Entry) iterator.next();
                nvps.add(new BasicNameValuePair((String) entry.getKey(),
                        (String) entry.getValue()));
            }
        }
        return nvps;
    }

    /**
     * json url Transformation map json參數標准化為map對象
     *
     * @param param
     * @return
     */
    public static Map<String, String> getUrlParams(String param) {
        Map<String, String> map = new HashMap<String, String>(0);
        if (param == null || param.length() <= 0) {
            return map;
        }
        String[] params = param.split("&");
        for (int i = 0; i < params.length; i++) {
            String[] p = params[i].split("=");
            if (p.length != 0) {
                map.put(p[0], p.length == 2 && p[1] != null && p[1].length() != 0 ? p[1] : "");
            }
        }
        return map;
    }

    /**
     * 判斷是否為IP對象
     *
     * @param addr
     * @return
     */
    public boolean isIP(String addr) throws Exception {
        try {
            if (addr.length() < 7 || addr.length() > 15 || "".equals(addr)) {
                return false;
            }
            /**
             * 判斷IP格式和范圍
             */
            String rexp = "([1-9]|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])(\\.(\\d|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])){3}";

            Pattern pat = Pattern.compile(rexp);

            Matcher mat = pat.matcher(addr);

            boolean ipAddress = mat.find();

            return ipAddress;
        } catch (Exception e) {
            throw new Exception("isIP exception 驗證IP失敗....." + msgException(e));
        }
    }

    /**
     * 判斷是否是圖片類型的文件
     *
     * @param html
     */
    public boolean isImage(String html) {
        if (StringUtil.isNotEmpty(html)) {
            if (ImageType.BMP.toString().equalsIgnoreCase(html)
                    || ImageType.gif.toString().equalsIgnoreCase(html)
                    || ImageType.jpeg.toString().equalsIgnoreCase(html)
                    || ImageType.png.toString().equalsIgnoreCase(html)) {
                return true;
            }
        } else {
            return false;
        }
        return false;
    }

    /**
     * 判斷是否是圖片類型的文件
     */
    public boolean isImage() {
        try {
            String requestType = getContentType(true);
            if (StringUtil.isNotEmpty(requestType)) {
                return isImage(requestType);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 圖片類型的枚舉
     */
    public enum ImageType {
        png, gif, jpg, jpeg, BMP,
    }

    /**
     * 繞過驗證-HTTPS
     *
     * @return
     * @throws NoSuchAlgorithmException
     * @throws KeyManagementException
     */
    public static SSLContext createIgnoreVerifySSL() throws KeyManagementException, NoSuchAlgorithmException {
        SSLContext sc = SSLContext.getInstance("SSLv3");

        // 實現一個X509TrustManager接口,用於繞過驗證,不用修改里面的方法
        X509TrustManager trustManager = new X509TrustManager() {
            @Override
            public void checkClientTrusted(
                    java.security.cert.X509Certificate[] paramArrayOfX509Certificate,
                    String paramString) throws CertificateException {
            }

            @Override
            public void checkServerTrusted(
                    java.security.cert.X509Certificate[] paramArrayOfX509Certificate,
                    String paramString) throws CertificateException {
            }

            @Override
            public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                return null;
            }
        };

        sc.init(null, new TrustManager[]{trustManager}, null);

        return sc;
    }

    /**
     * 打印錯誤的異常詳情
     *
     * @param e
     * @return
     */
    public String msgException(Exception e) {
        String msg = "";
        if (e != null && e.getStackTrace().length != 0) {
            StackTraceElement stackTraceElement = e.getStackTrace()[0];// 得到異常棧的首個元素
            msg = String.format("出現異常的類文件:%s,錯誤行數:%s,錯誤方法體:%s", stackTraceElement.getFileName(), stackTraceElement.getLineNumber(), stackTraceElement.getMethodName());
          /*  System.out.println("File="+stackTraceElement.getFileName());// 打印文件名
            System.out.println("Line="+stackTraceElement.getLineNumber());// 打印出錯行號
            System.out.println("Method="+stackTraceElement.getMethodName());// 打印出錯方法*/
        }
        return msg;
    }


}
  

代碼演示

1、使用搜狐網做示例:

1.代碼區域

 public static void main(String args[]) {
        try {
            /*聲明封裝類 默認請求是get*/
            HttpClient client = new HttpClient("http://www.sohu.com/picture/209151068?_f=index_news_25");
            client.setHttpHost("192.168.3.2:8888");
            System.out.println(client.request());

            client.setMethod("post");//登錄改為post請求
            client.setEntity("domain=sohu.com&callback=passport200007278089333261106_cb1512742508288&appid=1019&userid=XXXXXXXXXXXXXXXX&password=XXXXXXXXXXXXX&persistentcookie=0");
            client.setContentType("application/x-www-form-urlencoded");
            String loginHtml = client.request("http://passport.sohu.com/apiv2/login", "utf-8");//登錄搜狐網站
            System.out.println(loginHtml);

            client.setMethod("get");//登錄改為post請求
            loginHtml = client.request("http://passport.sohu.com/apiv2/toolbar/userinfo?callback=jQuery112404914197299918357_1512742508303&_=1512742508445", "utf-8");//獲取部分個人信息
            System.out.println(loginHtml);


        } catch (Exception e) {
            e.printStackTrace();
        }
    }

  2.響應請求

<!DOCTYPE html><html><head>    <title>壯觀!1180架無人機升空在廣州塔前表演-搜狐大視野-搜狐新聞</title>    <meta name="keywords" content="壯觀,1180,無人機,升空,空在,廣州,表演"/>  
<meta name="description" content="12月7日晚,廣州。在《祝酒歌》合唱歌聲中,1180架無人機編隊從海心沙飛起,亮燈形成“財富”兩個漢字,現場市民齊齊仰頭觀看。此次無人機編隊利用“科技舞蹈”,表達對2017廣州某論壇的歡迎,給出席論壇的嘉賓帶來驚喜。" /><meta charset="utf-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1"/><meta name="renderer" content="webkit"> <meta name="viewport" content="width=device-width, initial-scale=1,maximum-scale=1" />
<link rel="icon" href="//statics.itc.cn/web/static/images/pic/sohu-logo/favicon.ico" type="image/x-icon"/><link rel="shortcut icon" href="//statics.itc.cn/web/static/images/pic/sohu-logo/favicon.ico" type="image/x-icon"/>
<link rel="apple-touch-icon" sizes="57x57" href="//statics.itc.cn/web/static/images/pic/sohu-logo/logo-57.png" /><link rel="apple-touch-icon" sizes="72x72" href="//statics.itc.cn/web/static/images/pic/sohu-logo/logo-72.png" />
<link rel="apple-touch-icon" sizes="114x114" href="//statics.itc.cn/web/static/images/pic/sohu-logo/logo-114.png" /><link rel="apple-touch-icon" sizes="144x144" href="//statics.itc.cn/web/static/images/pic/sohu-logo/logo-144.png" />
<link href="//statics.itc.cn/web/v3/static/css/main-6708fcb576.css" rel="stylesheet"/><script> // 加載監控代碼</script><!--[if lt IE 9]><script src="//statics.itc.cn/web/v3/static/js/es5-shim-08e41cfc3e.min.js"></script>
<script src="//statics.itc.cn/web/v3/static/js/es5-sham-1d5fa1124b.min.js"></script><script src="//statics.itc.cn/web/v3/static/js/html5shiv-21fc8c2ba6.js"></script>
<link href="//statics.itc.cn/web/v3/static/css/ie8hack-9dce3c3b96.css" rel="stylesheet" /><![endif]--><script type="text/javascript">//解決IE8,IE9不支持console的問題(function() { var method; var noop = function() {};
var methods = [ 'assert', 'clear', 'count', 'debug', 'dir', 'dirxml', 'error', 'exception', 'group', 'groupCollapsed', 'groupEnd', 'info', 'log', 'markTimeline', 'profile', 'profileEnd', 'table', 'time'
, 'timeEnd', 'timeStamp', 'trace', 'warn' ]; var length = methods.length; var console = (window.console = window.console || {}); while (length--) { method = methods[length]; // Only stub undefin
ed methods. if (!console[method]) { console[method] = noop; } }}());</script><script type="text/javascript"> (function () { var html = document.getElementsByTagName("html")[0]; var width = Math.min(document.
documentElement.clientWidth, 790); width = width < 320 ? 320 : width; if (document.documentElement.clientWidth <= 1024) { html.style.fontSize = width / 790 * 79 + 'px'; } if (window.addEventListener) { window.
addEventListener('resize', resizeHandler); } else if (window.attachEvent) { window.attachEvent('onresize', resizeHandler); } function resizeHandler() { if (document.documentElement.clientWidth <= 1024) {
var width = Math.min(document.documentElement.clientWidth, 790); width = width < 320 ? 320 : width; html.style.fontSize = width / 790 * 79 + 'px'; } else { html.style.fontSize = "16px"; }
}; })();</script></head><body class="dsy-article"><div class="wrapper-box"><header id="main-header" class="article-head"> <div class="area"> <div class="head-nav left"> <ul>
<li class="index"><a href="http://www.sohu.com"><em class="icon-home icon"></em><em class="sohu-logo">搜狐首頁</em></a></li> <li><a href="http://news.sohu.com/">新聞</a></li>
<li><a href="http://sports.sohu.com/">體育</a></li> <li><a href="http://auto.sohu.com/">汽車</a></li> <li><a href="http://www.focus.cn/">房產</a></li>
<li><a href="http://travel.sohu.com/">旅游</a></li> <li><a href="http://learning.sohu.com/">教育</a></li> <li><a href="http://fashion.sohu.com/">時尚</a></li>
<li><a href="http://it.sohu.com/">科技</a></li> <li><a href="http://business.sohu.com/">財經</a></li> <li><a href="http://yule.sohu.com/">娛樂</a></li>
<li class="more-nav"><a href="javascript:void(0)">更多<em class="cor"></em></a> <div class="more-nav-box">
<a href="http://baobao.sohu.com/">母嬰</a> <a href="http://health.sohu.com/">健康</a> <a href="http://history.sohu.com/">歷史</a>
<a href="http://mil.sohu.com/">軍事</a> <a href="http://chihe.sohu.com/">美食</a>
<a href="http://cul.sohu.com/">文化</a> <a href="http://astro.sohu.com/">星座</a> <a href="http://society.sohu.com/">社會</a>
<a href="http://game.sohu.com/">游戲</a> <a href="http://fun.sohu.com/">搞笑</a> <a href="http://acg.sohu.com/">動漫</a>
<a href="http://pets.sohu.com/">寵物</a> </div> </li> </ul> </div>
<div id="head-login" class="right login"> <!--<span class="login-before"><a class="login-sohu" data-role="login-btn" href="javascript:void(0)"><i class="icon-user"></i>登錄狐友</a></span> <span class="login-after" style="display:none;">
<a href="#" target="_blank" class="user"><img src="images/pic/pic01.jpg" alt="我叫名字特別長"></a> <a href="#" target="_blank" class="write-link">寫文章</a> </span>-->
</div> </div> </header><div class="logo-search area"> <div class="left logo"><a href="javascript:void(0)">大視野</a></div> <div id="search" class="search left"><input type="text"
class="search-input left" value="大家正在搜:北京公租房:將為“新北京人”單划30%房源" /><a href="#" target="_blank" class="search-btn"><i class="search-icon icon"></i></a></div></div><div class="dsy-wrap"> <div class="dsy-contentA area clearfix">
<div class="article-title"> <h1 id="article-title-hash">壯觀!1180架無人機升空在廣州塔前表演</h1> <div class="info"> <span class="name"><img src="http://sucimg.itc.cn/avatarimg/965df594fbf44e3d86a2264f20d744b6_1506565321449"
alt="">一個普通的號</span><span class="time">2017-12-08 07:21:26</span> </div> <div class="func"> <span class="restart-link hid"><a href="javascript:;" class="link"><i class="icon restart-icon"></i><em class="num">重新瀏覽</em>
</a></span> <span class="com-link"> <a href="#comment_area" class="link"> <i class="icon com-icon"></i> <em data-role="comment-count" class="num">0</em> </a>
</span> <span class="zan-link" pic-likes="209151068"> <a href="javascript:;" class="link add-likes"> <i class="icon zan-icon"></i> <i class="icon unzan-icon hid"></i>
<em class="num"></em> </a> </span> </div> </div> <div class="pic-main"> <div class="pic-area">
<div class="picture"><i></i><img data-url="//5b0988e595225.cdn.sohucs.com/images/20171208/8678adb12de345e4a3e4047cf759338d.jpeg" src="//5b0988e595225.cdn.sohucs.com/c_zoom,h_77/images/20171208/8678adb12de345e4a3e4047cf759338d.jpeg" data-ev="10410060" alt=""></div>
<div class="picture hid"><i></i><img data-url="//5b0988e595225.cdn.sohucs.com/images/20171208/ebb3f770a164426f885fff1ba7d25fbf.jpeg" src="//5b0988e595225.cdn.sohucs.com/c_zoom,h_77/images/20171208/ebb3f770a164426f885fff1ba7d25fbf.jpeg"
alt=""></div> <div class="picture hid"><i></i><img data-url="//5b0988e595225.cdn.sohucs.com/images/20171208/d1962cd561214eada020425faac85f70.jpeg" src="//5b0988e595225.cdn.sohucs.com/c_zoom,h_77/images/20171208/d1962cd561214eada020
425faac85f70.jpeg" alt=""></div> <div class="picture hid"><i></i><img data-url="//5b0988e595225.cdn.sohucs.com/images/20171208/4b955cf5b33044e88584e0f07b66f4b7.jpeg" src="//5b0988e595225.cdn.sohucs.com/c_zoom,h_77/images/20171208/4
b955cf5b33044e88584e0f07b66f4b7.jpeg" alt=""></div> <div class="picture hid"><i></i><img data-url="//5b0988e595225.cdn.sohucs.com/images/20171208/75a2e6dcdd714089a3503c3820bc2631.jpeg" src="//5b0988e595225.cdn.sohucs.com/c_zoom,h_77
/images/20171208/75a2e6dcdd714089a3503c3820bc2631.jpeg" alt=""></div> <div class="picture hid"><i></i><img data-url="//5b0988e595225.cdn.sohucs.com/images/20171208/22d27f5cc0c54435a8bdbd2bb80f0f87.jpeg" src="//5b0988e595225.cdn.sohuc
s.com/c_zoom,h_77/images/20171208/22d27f5cc0c54435a8bdbd2bb80f0f87.jpeg" alt=""></div> <div class="picture hid"><i></i><img data-url="//5b0988e595225.cdn.sohucs.com/images/20171208/42e389e7c76a4dabae945ed91bf5e2de.jpeg" src="//5b0988e595225.cdn.sohucs.com/c_zoom,h_77/images/20171208/42e389e7c76a4dabae945ed91bf5e2de.jpeg" alt=""></div> <div class="picture hid"><i></i><img data-url="//5b0988e595225.cdn.sohucs.com/images/20171208/68652014966b4f53a0152af1c95dcdb7.jpeg" src="//5b0988e595225.cdn.sohucs.com/c_zoom,h_77/images/20171208/68652014966b4f53a0152af1c95dcdb7.jpeg" alt=""></div> <div class="picture hid"><i></i><img data-url="//5b0988e595225.cdn.sohucs.com/images/20171208/4c6ee145a6234594b8e081ad8831f8ba.jpeg" src="//5b0988e595225.cdn.sohucs.com/c_zoom,h_77/images/20171208/4c6ee145a6234594b8e081ad8831f8ba.jpeg" data-ev="10410059" alt=""></div> <div class="switch-btn"> <a href="javascript:;" class="btn-pre hid pre-img-btn"> <span class="bg"></span> <i class="icon pre-icon hid" title="上一圖片"></i></a> <a href="javascript:;" class="btn-next next-img-btn"> <span class="bg"></span> <i class="icon next-icon hid" title="下一圖片"></i> </a> </div> <div class="explain"> <div class="bg-area"></div> <div class="pic-number"><em class="num">1</em>/<em class="total">12</em></div> <div class="pic-exp"> <div class="txt"> <p>12月7日晚,廣州。在《祝酒歌》合唱歌聲中,1180架無人機編隊從海心沙飛起,亮燈形成“財富”兩個漢字,現場市民齊齊仰頭觀看。此次無人機編隊利用“科技舞蹈”,表達對2017廣州某論壇的歡迎,給出席論壇的嘉賓帶來驚喜。</p> <p class="hid">據悉,這是繼2017年元宵節廣州在海心沙創造的1000架無人機表演破吉尼斯世界紀錄之后,帶來的數量更多的無人機編隊飛行表演。圖為無人機拼湊“財富”二字。</p> <p class="hid">現場圖。</p> <p class="hid">現場圖。</p> <p class="hid">現場圖。</p> <p class="hid">現場圖。</p> <p class="hid">現場圖。</p> <p class="hid">現場圖。</p> <p class="hid">現場圖。</p> </div> </div> </div> <div class="operation"> <a href="javascript:;" data-cv="10410064" class="btn-original btn-include-text" data-cv=""> <span class="show-hint-text hid">查看原圖</span> </a> <a href="javascript:;" data-cv="10410063" class="btn-slide btn-include-text" data-cv=""> <span class="show-hint-text hid">全屏模式</span> </a> </div> </div> <div class="pic-small-group"> <div class="pic-list"> <div class="scroll"> <div class="con"> <div class="pic cur"><img data-url="//5b0988e595225.cdn.sohucs.com/images/20171208/8678adb12de345e4a3e4047cf759338d.jpeg" src="//5b0988e595225.cdn.sohucs.com/c_zoom,h_77/images/20171208/8678adb12de345e4a3e4047cf759338d.jpeg" alt=""> <div class="bg"></div> </div> <div class="pic"><img data-url="//5b0988e595225.cdn.sohucs.com/images/20171208/ebb3f770a164426f885fff1ba7d25fbf.jpeg" src="//5b0988e595225.cdn.sohucs.com/c_zoom,h_77/images/20171208/ebb3f770a164426f885fff1ba7d25fbf.jpeg" alt=""> <div class="bg"></div> </div> <div class="pic"><img data-url="//5b0988e595225.cdn.sohucs.com/images/20171208/d1962cd561214eada020425faac85f70.jpeg" src="//5b0988e595225.cdn.sohucs.com/c_zoom,h_77/images/20171208/d1962cd561214eada020425faac85f70.jpeg" alt=""> <div class="bg"></div> </div> <div class="pic"><img data-url="//5b0988e595225.cdn.sohucs.com/images/20171208/4b955cf5b33044e88584e0f07b66f4b7.jpeg" src="//5b0988e595225.cdn.sohucs.com/c_zoom,h_77/images/20171208/4b955cf5b33044e88584e0f07b66f4b7.jpeg" alt=""> <div class="bg"></div> </div> <div class="pic"><img data-url="//5b0988e595225.cdn.sohucs.com/images/20171208/75a2e6dcdd714089a3503c3820bc2631.jpeg" src="//5b0988e595225.cdn.sohucs.com/c_zoom,h_77/images/20171208/75a2e6dcdd714089a3503c3820bc2631.jpeg" alt=""> <div class="bg"></div> </div> <div class="pic"><img data-url="//5b0988e595225.cdn.sohucs.com/images/20171208/22d27f5cc0c54435a8bdbd2bb80f0f87.jpeg" src="//5b0988e595225.cdn.sohucs.com/c_zoom,h_77/images/20171208/22d27f5cc0c54435a8bdbd2bb80f0f87.jpeg" alt=""> <div class="bg"></div> </div> <div class="pic"><img data-url="//5b0988e595225.cdn.sohucs.com/images/20171208/42e389e7c76a4dabae945ed91bf5e2de.jpeg" src="//5b0988e595225.cdn.sohucs.com/c_zoom,h_77/images/20171208/42e389e7c76a4dabae945ed91bf5e2de.jpeg" alt=""> <div class="bg"></div> </div> <div class="pic"><img data-url="//5b0988e595225.cdn.sohucs.com/images/20171208/68652014966b4f53a0152af1c95dcdb7.jpeg" src="//5b0988e595225.cdn.sohucs.com/c_zoom,h_77/images/20171208/68652014966b4f53a0152af1c95dcdb7.jpeg" alt=""> <div class="bg"></div> </div> <div class="pic"><img data-url="//5b0988e595225.cdn.sohucs.com/images/20171208/4c6ee145a6234594b8e081ad8831f8ba.jpeg" src="//5b0988e595225.cdn.sohucs.com/c_zoom,h_77/images/20171208/4c6ee145a6234594b8e081ad8831f8ba.jpeg" alt=""> <div class="bg"></div> </div> </div> </div> <div class="btns"><a class="btnl unbtnl pre-pic-group" href="javascript:void(0)"></a><a class="btnr next-pic-group" href="javascript:void(0)"></a></div> </div> </div> </div> <div class="pic-last hid"> <div class="last-mod clearfix"> <div class="title">大家正在看</div> <div class="left pic-group"> <ul> <li><a title="洛杉磯當局預警:山火極危險 將有爆炸性增長" class="jump-next-pic" id="209185533" href="/picture/209185533" data-cv="10410061" target="_blank"><img src="//5b0988e595225.cdn.sohucs.com/a_auto,c_cut,x_0,y_0,w_640,h_426/images/20171208/e1e939a8d84f449cabd030b09aa2ab99.jpeg" alt=""><span>洛杉磯當局預警:山火極危險 將有爆炸性增長</span></a></li> <li><a title="鄭州警方破獲特大外匯交易軟件詐騙案刑拘35人" class="jump-next-pic" id="209182938" href="/picture/209182938" data-cv="10410061" target="_blank"><img src="//5b0988e595225.cdn.sohucs.com/a_auto,c_cut,x_0,y_0,w_930,h_620/images/20171208/17529c9a8fb243d6a10a09d56634d360.jpeg" alt=""><span>鄭州警方破獲特大外匯交易軟件詐騙案刑拘35人</span></a></li> <li><a title="大佬們的保鏢對比 李嘉誠的是退伍特種兵" class="jump-next-pic" id="209182740" href="/picture/209182740" data-cv="10410061" target="_blank"><img src="//5b0988e595225.cdn.sohucs.com/a_auto,c_cut,x_0,y_13,w_599,h_400/images/20171208/a583d1d2281046019c0bee9866731b05.jpeg" alt=""><span>大佬們的保鏢對比 李嘉誠的是退伍特種兵</span></a></li> <li><a title="成都電子科大迎最美銀杏季" class="jump-next-pic" id="209182230" href="/picture/209182230" data-cv="10410061" target="_blank"><img src="//5b0988e595225.cdn.sohucs.com/a_auto,c_cut,x_125,y_0,w_762,h_508/images/20171208/88337338e83c44ad8f156c8fa42a6e57.jpeg" alt=""><span>成都電子科大迎最美銀杏季</span></a></li> <li><a title="王菲、馮小剛的豪宅跟她的相比簡直太寒酸!" class="jump-next-pic" id="209181480" href="/picture/209181480" data-cv="10410061" target="_blank"><img src="//5b0988e595225.cdn.sohucs.com/a_auto,c_cut,x_0,y_10,w_586,h_391/images/20171208/301449365f6041d38289174cd2df60cc.jpeg" alt=""><span>王菲、馮小剛的豪宅跟她的相比簡直太寒酸!</span></a></li> <li><a title="史上最奇葩汽車造型 這些車主腦洞真大" class="jump-next-pic" id="209180962" href="/picture/209180962" data-cv="10410061" target="_blank"><img src="//5b0988e595225.cdn.sohucs.com/a_auto,c_cut,x_0,y_12,w_640,h_426/images/20171208/a3ff6181309a40deb0e4f3e008121f7f.jpeg" alt=""><span>史上最奇葩汽車造型 這些車主腦洞真大</span></a></li> </ul> </div> <div class="right last-ri"> <div class="godR"> </div> </div> </div> <div class="last-btn"><a href="javascript:;" class="bl pre-img-btn"></a> <a href="/picture/209185533" data-cv="10410062" class="br next-pic-collection"></a></div> </div> </div> <div class="original-box"> <div class="img-wrap"> <div class="original-pic"><img src="" alt=""></div> </div> <span target="_blank" class="original-close"></span> </div> <div class="slide-box"> <div class="slide-btn"> <span target="_blank" class="slide-quit btn-include-text"> <span class="show-hint-text hid">退出全屏</span> </span> <span target="_blank" class="slide-stop btn-include-text"> <span class="show-hint-text hid">暫停</span> </span> <span target="_blank" class="slide-play hid btn-include-text"> <span class="show-hint-text hid">播放</span> </span> </div> <div class="slide-main"> <div class="slide-pic"> <div class="slide-con"> <div class="picture show"><i></i><img data-url="//5b0988e595225.cdn.sohucs.com/images/20171208/8678adb12de345e4a3e4047cf759338d.jpeg" src="//5b0988e595225.cdn.sohucs.com/c_zoom,h_77/images/20171208/8678adb12de345e4a3e4047cf759338d.jpeg" alt=""></div> <div class="picture"><i></i><img data-url="//5b0988e595225.cdn.sohucs.com/images/20171208/ebb3f770a164426f885fff1ba7d25fbf.jpeg" src="//5b0988e595225.cdn.sohucs.com/c_zoom,h_77/images/20171208/ebb3f770a164426f885fff1ba7d25fbf.jpeg" alt=""></div> <div class="picture"><i></i><img data-url="//5b0988e595225.cdn.sohucs.com/images/20171208/d1962cd561214eada020425faac85f70.jpeg" src="//5b0988e595225.cdn.sohucs.com/c_zoom,h_77/images/20171208/d1962cd561214eada020425faac85f70.jpeg" alt=""></div> <div class="picture"><i></i><img data-url="//5b0988e595225.cdn.sohucs.com/images/20171208/4b955cf5b33044e88584e0f07b66f4b7.jpeg" src="//5b0988e595225.cdn.sohucs.com/c_zoom,h_77/images/20171208/4b955cf5b33044e88584e0f07b66f4b7.jpeg" alt=""></div> <div class="picture"><i></i><img data-url="//5b0988e595225.cdn.sohucs.com/images/20171208/75a2e6dcdd714089a3503c3820bc2631.jpeg" src="//5b0988e595225.cdn.sohucs.com/c_zoom,h_77/images/20171208/75a2e6dcdd714089a3503c3820bc2631.jpeg" alt=""></div> <div class="picture"><i></i><img data-url="//5b0988e595225.cdn.sohucs.com/images/20171208/22d27f5cc0c54435a8bdbd2bb80f0f87.jpeg" src="//5b0988e595225.cdn.sohucs.com/c_zoom,h_77/images/20171208/22d27f5cc0c54435a8bdbd2bb80f0f87.jpeg" alt=""></div> <div class="picture"><i></i><img data-url="//5b0988e595225.cdn.sohucs.com/images/20171208/42e389e7c76a4dabae945ed91bf5e2de.jpeg" src="//5b0988e595225.cdn.sohucs.com/c_zoom,h_77/images/20171208/42e389e7c76a4dabae945ed91bf5e2de.jpeg" alt=""></div> <div class="picture"><i></i><img data-url="//5b0988e595225.cdn.sohucs.com/images/20171208/68652014966b4f53a0152af1c95dcdb7.jpeg" src="//5b0988e595225.cdn.sohucs.com/c_zoom,h_77/images/20171208/68652014966b4f53a0152af1c95dcdb7.jpeg" alt=""></div> <div class="picture"><i></i><img data-url="//5b0988e595225.cdn.sohucs.com/images/20171208/4c6ee145a6234594b8e081ad8831f8ba.jpeg" src="//5b0988e595225.cdn.sohucs.com/c_zoom,h_77/images/20171208/4c6ee145a6234594b8e081ad8831f8ba.jpeg" alt=""></div> </div> </div> <div class="slide-lr"> <span class="btn-pre"></span> <span class="btn-next"></span> </div> <div class="slide-explain"> <span class="btn-fold" title="隱藏"> <span class="bg-area"></span> <i class="icon fold-icon"></i> </span> <span class="btn-unfold hid" title="顯示"> <span class="bg-area"></span> <i class="icon unfold-icon"></i> </span> <div class="explain"> <div class="bg-area"></div> <div class="pic-number"><em class="num">1</em>/<em class="total">12</em></div> <div class="pic-exp"> <h3>壯觀!1180架無人機升空在廣州塔前表演</h3> <p>12月7日晚,廣州。在《祝酒歌》合唱歌聲中,1180架無人機編隊從海心沙飛起,亮燈形成“財富”兩個漢字,現場市民齊齊仰頭觀看。此次無人機編隊利用“科技舞蹈”,表達對2017廣州某論壇的歡迎,給出席論壇的嘉賓帶來驚喜。</p> <p class="hid">據悉,這是繼2017年元宵節廣州在海心沙創造的1000架無人機表演破吉尼斯世界紀錄之后,帶來的數量更多的無人機編隊飛行表演。圖為無人機拼湊“財富”二字。</p> <p class="hid">現場圖。</p> <p class="hid">現場圖。</p> <p class="hid">現場圖。</p> <p class="hid">現場圖。</p> <p class="hid">現場圖。</p> <p class="hid">現場圖。</p> <p class="hid">現場圖。</p> </div> </div> </div> </div> </div></div> <div class="dsy-contentB area clearfix"> <div class="left main"><div class="article-oper clearfix"> <div class="article-oper-l left"> <span class="read-num">閱讀 (<em data-role="pv" data-val="22"></em>)</span> </div> <div class="article-oper-r right"> <span class="uninterested" id="uninterested"></span> <a class="complain-link" target="_blank" href="http://quan.sohu.com/q/545c9b6bf6c43b5569fe64a2"><em class="complain-icon icon"></em>投訴</a> </div></div><div class="article-recom clear" id="sogou-words"></div> <div class="god-main" data-role="god_column"></div><div class="comment" id="comment_area"> <div id="mp-comment" sid="209151068"></div> </div> <div class="god-main" data-role="god_column"></div> </div> <div class="right sidebar"> <div class="bordR godR" data-role="godR"></div><div class="hot-article bordR clearfix" data-role='hot-news'></div> <div class="bordR godR" data-role="godR"></div> </div><div id="float-btn" class="float-links"></div> </div></div><script src="//statics.itc.cn/web/v3/static/js/lib-111eab4f1d.js"></script><!--<script src="//statics.itc.cn/web/v3/static/js/ie8hack-07e05e83f1.js"></script>--><script src="//txt.go.sohu.com/ip/soip"></script><script src="//statics.itc.cn/web/v3/static/js/main-2c6afe69e7.js"></script><script src="//js.sohu.com/pv.js"></script><script charset="utf8"> try { window.sohu_mp.pic_collections({ channel_id: "43", news_id: "209151068", back_url: "//www.sohu.com", media_id: "99984058", title: "壯觀!1180架無人機升空在廣州塔前表演", }) } catch (e) { var html = '<div class="err-js">' + '<span><em class="icon err-js-icon"></em>JS加載錯誤,請重新加載。</span>' + '<a href="javascript:window.location.reload()" target="_blank" class="cached-btn"' + '><em class="icon-cached"></em>刷新</a></div>'; $(document.body).prepend(html); console.log(e) // Raven.captureException(e); // 此處應捕獲錯誤 }</script><!--[if lt IE 8]><script type="text/javascript">(function(){ var ua = navigator.userAgent; var version; var html = '<div class="area clear">' + '<div class="ie-low">' + '<p>您的瀏覽器版本過低<br>為了更好的體驗,請升級你的瀏覽器。</p>' + '<h5><a href="https://ie.sogou.com" target="_blank" class="upgrade-btn">馬上升級</a></h5>' + '</div></div>'; if (/MSIE ([^;]+)/.test(ua)) { version = parseInt(RegExp["$1"]); if (version<8) { document.body.innerHTML=html; var reg = new RegExp("(^| )SUV=([^;]*)(;|$)"); var suvs = unescape(document.cookie.match(reg)[2]); var spv_server_src = "http://pv.sohu.com/action.gif?actionId=10210078&SUV="+suvs; var scripts = document.createElement('script'); scripts.src = spv_server_src; document.body.appendChild(scripts); Raven.captureException(new Error('ie'+version)); } }})()</script><![endif]--></body></html> <script> document.domain = "sohu.com"; parent.passport200007278089333261106_cb1512742508288({"code":0,"data":"","msg":"登陸成功"});</script> jQuery112404914197299918357_1512742508303({"code":0,"data":{"avatar":"http://photo.pic.sohu.com/images/oldblog/person/11111.gif","isMpUser":0,"nickname":"狐狐網友"},"msg":"get userinfo success"}) ()

  

  

方法概要

方法  
限定符和類型 方法和說明
void closeClient(boolean isInit)
關閉client連接對象 釋放對象 並重新初始化
void closeHttpResponse()
關閉線程池,防止堵塞(這里需要手動調用,由於這里吧響應和請求封裝在一個類了所以只能在外面手動調用釋放)
void closeHttpResponse(org.apache.http.HttpEntity entity)
關閉線程池,防止堵塞(這里需要手動調用,由於這里吧響應和請求封裝在一個類了所以只能在外面手動調用釋放) 如果出現發送httpclient請求后一直無響應,應該是線程池占用完了,所以每次調用request后記得在finally手動調用本方法CloseHttpResponse
static javax.net.ssl.SSLContext createIgnoreVerifySSL()
繞過驗證-HTTPS
org.apache.http.Header getContentType()
獲取返回值的類型
java.lang.String getContentType(boolean isFormat)
獲取響應的實體類型 並獲取具體類型:jpeg/html/png/gif......
org.apache.http.client.methods.CloseableHttpResponse getHttpResponse() 
int getStatusCode()
獲取返回值的狀態 100 客戶端可以繼續 101 指示服務器正根據 Upgrade 頭切換協議 200 請求正常成功 201 指示請求成功並在服務器上創建了一個新資源 202 指示已接受請求進行處理但處理尚未完成 203 指示客戶端呈現的元信息並不源自服務器 204 指示請求成功但沒有返回新信息 205 指示代理應該 重置導致請求被發送的文檔視圖 206 指示服務器已完成對資源的部分 GET 請求 300 請求的資源對應於表示形式集合中的某種表示形式,每種表示形式都有自己的特定位置 301 指示已經將資源永久地移動到了某個新位置,並且將來的引用應將新 URI 用於其請求 302 指示已經將資源暫時地移動到了另一個位置,但將來的引用仍應使用原來的 URI 訪問該資源。
static java.util.Map<java.lang.String,java.lang.String> getUrlParams(java.lang.String param)
json url Transformation map json參數標准化為map對象
void initHttpClinet()
初始化clinet請求對象-並初始化HTTP/HTTPS兩種協議
void initHttpRequest()
初始化htpclinet的請求對象
boolean isImage()
判斷是否是圖片類型的文件
boolean isImage(java.lang.String html)
判斷是否是圖片類型的文件
boolean isIP(java.lang.String addr)
判斷是否為IP對象
java.lang.String msgException(java.lang.Exception e)
打印錯誤的異常詳情
java.lang.String readLineInputStream(org.apache.http.HttpEntity httpEntity)
重載讀取流
java.lang.String readLineInputStream(java.io.InputStream inputStream)
重載讀取流
java.lang.String readLineInputStream(java.lang.String utf, org.apache.http.HttpEntity httpEntity)
重載讀取流
java.lang.String readLineInputStream(java.lang.String utf, java.io.InputStream inputStream)
重載讀取流
java.lang.String request()
請求數據並返回字符串類型
org.apache.http.HttpEntity request(java.lang.String url)
請求數據並返回一個數據實體
byte[] request(java.lang.String url, java.lang.Integer numBer)
請求並返回byte數組數據
java.lang.String request(java.lang.String url, java.lang.String utf)
請求數據並返回數據 自定義流轉文本編碼格式
void setAccept(java.lang.String accept)
客戶端能夠接收的內容類型
void setAutoSaveReferer(boolean autoSaveReferer)
自動保存上一個請求源 true 自動保存/false 不自動保存(默認)
void setConnectionRequestTimeout(int connectionRequestTimeout)
請求超時的時間 單位毫秒
void setConnectTimeout(int connectTimeout)
連接被阻塞超時 單位毫秒
void setContentType(java.lang.String contentType)
請求的與實體對應的MIME信息
void setCookie(java.lang.String cookie)
設置cookie
void setCredentials(java.lang.String userName, java.lang.String userPwd)
服務器認證信息
void setEntity(java.util.Map<java.lang.String,java.lang.String> params)
設置post請求參數 map
void setEntity(java.lang.String params)
設置post請求參數 string
void setEntity(org.apache.http.entity.StringEntity json)
設置post請求參數 map
void setHeader(java.util.Map<java.lang.String,java.lang.String> header)
設置Header
void setHeader(java.lang.String headerName, java.lang.String headerVal) 
void setHttpHost(java.lang.String hostVal)
設置HTTP請求代理模式 格式:127.0.0.0:8888
static void setMaxConnPerRoute(int maxConnPerRoute)
實際的單個連接池大小,如tps定為50,那就配置50
static void setMaxConnTotal(int maxConnTotal)
最大的請求連接數 注意:最大不要超過1000
void setMethod(java.lang.String method)
設置提交方式 get/post
void setOrigin(java.lang.String origin)
請求的來源-post使用,等同於Referer頭
void setReferer(java.lang.String referer)
先前網頁的地址
void setSocketTimeout(int socketTimeout)
服務器響應超時 單位毫秒
void setUserAgent(java.lang.String userAgent)
注明客戶端請求的觸發器版本
byte[] toByteArrays(java.io.InputStream in, java.lang.Integer numBer)
文件流轉byte數組


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM