HttpClient4.5使用http和Socks代理访问

标签: http 代理
2019-08-28 阅读(141)

如何使用HttpClient代理请求。例如想要获取某国外网站,现已有翻墙代理服务器,在使用httpClient代码请求国外网站时通过设置指定代理即可访问。



第一种:http

实现类 TestHttp.java

package com;

import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;

import java.io.IOException;

public class TestHttp {

    public static void main(String[] args) throws Exception {
        //创建客户端
        CloseableHttpClient httpClient = HttpClientBuilder.create().build();

        HttpGet httpGet = null;
        CloseableHttpResponse response = null;
        HttpEntity entity = null;
        try {
            httpGet = new HttpGet("https://www.youtube.com");
            //代理
            HttpHost proxy = new HttpHost("192.168.1.20", 8087);
            RequestConfig reqConfig = RequestConfig.custom().setProxy(proxy).build();
            httpGet.setConfig(reqConfig);
            
            response = httpClient.execute(httpGet);
            int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode != 200)
                throw new Exception("请求失败,状态:" + statusCode);

            entity = response.getEntity();
            String result = null;
            if (entity != null)
                result = EntityUtils.toString(entity, "UTF-8");

            System.out.println(result);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (entity != null)
                    EntityUtils.consume(entity);
                if (response != null)
                    response.close();
                if (httpGet != null)
                    httpGet.abort();
                if (httpClient != null)
                    httpClient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

}




第二种:socks5

FakeDnsResolver.java 覆盖OS提供的正常DNS查找

package com;

import org.apache.http.conn.DnsResolver;

import java.net.InetAddress;
import java.net.UnknownHostException;

public class FakeDnsResolver implements DnsResolver {

    @Override
    public InetAddress[] resolve(String host) throws UnknownHostException {
        return new InetAddress[]{InetAddress.getByAddress(new byte[]{1, 1, 1, 1})};
    }

}


MyConnectionSocketFactory.java 继承PlainConnectionSocketFactory创建和初始化普通(未加密)套接字的默认工厂

package com;

import org.apache.http.HttpHost;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.protocol.HttpContext;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.Socket;

public class MyConnectionSocketFactory extends PlainConnectionSocketFactory {

    @Override
    public Socket createSocket(final HttpContext context) throws IOException {
        InetSocketAddress socksAddr = (InetSocketAddress) context.getAttribute("socks.address");
        Proxy proxy = new Proxy(Proxy.Type.SOCKS, socksAddr);
        return new Socket(proxy);
    }

    @Override
    public Socket connectSocket(int connectTimeout, Socket socket, HttpHost host, InetSocketAddress remoteAddress, InetSocketAddress localAddress, HttpContext context) throws IOException {
        InetSocketAddress unresolvedRemote = InetSocketAddress.createUnresolved(host.getHostName(), remoteAddress.getPort());
        return super.connectSocket(connectTimeout, socket, host, unresolvedRemote, localAddress, context);
    }

}


类 MySSLConnectionSocketFactory.java 继承SSLConnectionSocketFactory这SSL连接的分层套接字工厂

package com;

import org.apache.http.HttpHost;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.protocol.HttpContext;

import javax.net.ssl.SSLContext;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.Socket;

public class MySSLConnectionSocketFactory extends SSLConnectionSocketFactory {

    public MySSLConnectionSocketFactory(final SSLContext sslContext) {
        super(sslContext);
    }

    @Override
    public Socket createSocket(final HttpContext context) throws IOException {
        InetSocketAddress socksAddr = (InetSocketAddress) context.getAttribute("socks.address");
        Proxy proxy = new Proxy(Proxy.Type.SOCKS, socksAddr);
        return new Socket(proxy);
    }

    @Override
    public Socket connectSocket(int connectTimeout, Socket socket, HttpHost host, InetSocketAddress remoteAddress, InetSocketAddress localAddress, HttpContext context) throws IOException {
        InetSocketAddress unresolvedRemote = InetSocketAddress.createUnresolved(host.getHostName(), remoteAddress.getPort());
        return super.connectSocket(connectTimeout, socket, host, unresolvedRemote, localAddress, context);
    }

}


实现类 TestSocks.java

package com;

import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.util.EntityUtils;

import java.io.IOException;
import java.net.InetSocketAddress;

public class TestSocks {

    public static void main(String[] args) throws Exception {
        //注册ConnectionSocketFactory
        Registry<ConnectionSocketFactory> reg = RegistryBuilder.<ConnectionSocketFactory>create()
                .register("http", new MyConnectionSocketFactory())
                .register("https", new MySSLConnectionSocketFactory(SSLContexts.createSystemDefault())).build();
        //连接池管理
        PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(reg, new FakeDnsResolver());
        //创建客户端
        CloseableHttpClient httpClient = HttpClientBuilder.create().setConnectionManager(cm).build();
        //Socket代理
        InetSocketAddress socksAddr = new InetSocketAddress("192.168.1.20", 8088);
        HttpClientContext context = HttpClientContext.create();
        context.setAttribute("socks.address", socksAddr);

        HttpGet httpGet = null;
        CloseableHttpResponse response = null;
        HttpEntity entity = null;
        try {
            httpGet = new HttpGet("https://www.youtube.com");

            response = httpClient.execute(httpGet, context);
            int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode != 200)
                throw new Exception("请求失败,状态:" + statusCode);

            entity = response.getEntity();
            String result = null;
            if (entity != null)
                result = EntityUtils.toString(entity, "UTF-8");

            System.out.println(result);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (entity != null)
                    EntityUtils.consume(entity);
                if (response != null)
                    response.close();
                if (httpGet != null)
                    httpGet.abort();
                if (httpClient != null)
                    httpClient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

}




运行结果

已某知名视频网站Youtube为例。

请求返回内容.png




附录

使用的httpClient版本:

使用包
httpclient-4.5.3.jar

重要依赖包
commons-codec-1.9.jar
commons-logging-1.2.jar
httpcore-4.4.6.jar

maven:

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




原创文章,转载请注明出处:https://www.weizhixi.com/user/index/article/id/94.html

分类:
点击(163) 阅读(141) 举报