收集于网络,按道理可发送HTTP或HTTPS的代理请求。由于条件限制,还未真正验证过,还请诸位大神指点。 package com.qhins.wcthl.utils;import java.io.BufferedReader;import java.io.IOException;import java.io
package com.qhins.wcthl.utils;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.Proxy.Type;
import java.net.URL;
import java.net.URLConnection;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import org.apache.log4j.Logger;
import org.apache.tomcat.util.codec.binary.Base64;
import org.springframework.util.StringUtils;
/**
*
* 代理HTTP
*
* @author 小精豆
* @version 【版本号, 2017年11月3日】
* @see 【相关类/方法】
* @since 【产品/模块版本】
*/
public class HTTPProxyUtils
{
private static final Logger logger = Logger.getLogger(HTTPProxyUtils.class);
private static final String HTTP = "http://";
private static final String HTTPS = "https://";
/**
* HTTPS--代理POST请求
* */
public static String sendHttpsPostByProxy(String url, String param,
String host, int port, String user, String password)
{
PrintWriter out = null;
BufferedReader in = null;
String result = "";
try
{
URL realUrl = new URL(url);
//指定信任HTTPS
SSLContext ssl = SSLContext.getInstance("SSL");
ssl.init(null,
new TrustManager[] { new TrustAnyTrustManager() },
new SecureRandom());
//创建代理虽然是https也是Type.HTTP
Proxy proxy = new Proxy(Type.HTTP,
new InetSocketAddress(host, port));
// 打开和URL之间的连接
HttpsURLConnection conn = (HttpsURLConnection) realUrl
.openConnection(proxy);
//用户登录认证
conn = handleAuth(user, password, conn);
//设置https连接配置
conn.setSSLSocketFactory(ssl.getSocketFactory());
conn.setHostnameVerifier(new TrustAnyHostnameVerifier());
// 设置通用的请求属性
conn.setRequestProperty("accept", "*/*");
conn.setRequestProperty("connection", "Keep-Alive");
conn.setRequestProperty("user-agent",
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
// 发送POST请求必须设置如下两行
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setReadTimeout(10000);
conn.setConnectTimeout(10000);
// 获取URLConnection对象对应的输出流
out = new PrintWriter(conn.getOutputStream());
// 发送请求参数
out.print(param);
// flush输出流的缓冲
out.flush();
// 定义BufferedReader输入流来读取URL的响应
in = new BufferedReader(
new InputStreamReader(conn.getInputStream()));
String line;
while ((line = in.readLine()) != null)
{
result += line;
}
conn.disconnect();
}
catch (Exception e)
{
System.out.println("发送 POST 请求出现异常!" + e);
e.printStackTrace();
}
//使用finally块来关闭输出流、输入流
finally
{
try
{
if (out != null)
{
out.close();
}
if (in != null)
{
in.close();
}
}
catch (IOException ex)
{
ex.printStackTrace();
}
}
return result;
}
/**
* HTTP--代理POST请求
* */
public static String sendHttpPostByProxy(String url, String param,
String host, int port, String user, String password)
{
PrintWriter out = null;
BufferedReader in = null;
String result = "";
try
{
URL realUrl = new URL(url);
//设置代理
Proxy proxy = new Proxy(Type.HTTP,
new InetSocketAddress(host, port));
// 打开和URL之间的连接
HttpURLConnection conn = (HttpURLConnection) realUrl
.openConnection(proxy);
//用户登录认证
conn = handleAuth(user, password, conn);
// 设置通用的请求属性
conn.setRequestProperty("accept", "*/*");
conn.setRequestProperty("connection", "Keep-Alive");
conn.setRequestProperty("user-agent",
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
// 发送POST请求必须设置如下两行
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setReadTimeout(10000);
conn.setConnectTimeout(10000);
// 获取URLConnection对象对应的输出流
out = new PrintWriter(conn.getOutputStream());
// 发送请求参数
out.print(param);
// flush输出流的缓冲
out.flush();
// 定义BufferedReader输入流来读取URL的响应
in = new BufferedReader(
new InputStreamReader(conn.getInputStream()));
String line;
while ((line = in.readLine()) != null)
{
result += line;
}
conn.disconnect();
}
catch (Exception e)
{
System.out.println("发送 POST 请求出现异常!" + e);
e.printStackTrace();
}
//使用finally块来关闭输出流、输入流
finally
{
try
{
if (out != null)
{
out.close();
}
if (in != null)
{
in.close();
}
}
catch (IOException ex)
{
ex.printStackTrace();
}
}
return result;
}
/**
* 证书信任管理器
*
* @author liuhy001
* @version 【版本号, 2017年11月2日】
* @see 【相关类/方法】
* @since 【产品/模块版本】
*/
private static class TrustAnyTrustManager implements X509TrustManager
{
/**
* 该方法检查客户端的证书,若不信任该证书则抛出异常。
* 由于我们不需要对客户端进行认证,因此我们只需要执行默认的信任管理器的这个方法。
* JSSE中,默认的信任管理器类为TrustManager。
* @param arg0
* @param arg1
* @throws CertificateException
*/
@Override
public void checkClientTrusted(X509Certificate[] arg0, String arg1)
throws CertificateException
{
}
/**
* 该方法检查服务器的证书,若不信任该证书同样抛出异常。
* 通过自己实现该方法,可以使之信任我们指定的任何证书。
* 在实现该方法时,也可以简单的不做任何处理,即一个空的函数体,由于不会抛出异常,它就会信任任何证书。
* @param arg0
* @param arg1
* @throws CertificateException
*/
@Override
public void checkServerTrusted(X509Certificate[] arg0, String arg1)
throws CertificateException
{
}
/**
* 返回受信任的X509证书数组。
* @return
*/
@Override
public X509Certificate[] getAcceptedIssuers()
{
return new X509Certificate[] {};
}
}
/**
* 此类是用于主机名验证的基接口
* 在握手期间,如果 URL 的主机名和服务器的标识主机名不匹配,则验证机制可以回调此接口的实现程序来确定是否应该允许此连接。
* 策略可以是基于证书的或依赖于其他验证方案。
* 当验证 URL 主机名使用的默认规则失败时使用这些回调。
* 参数:
* hostname - 主机名
* session - 到主机的连接上使用的 SSLSession
* 返回: 如果主机名是可接受的,则返回 true
* @author liuhy001
* @version 【版本号, 2017年11月2日】
* @see 【相关类/方法】
* @since 【产品/模块版本】
*/
private static class TrustAnyHostnameVerifier implements HostnameVerifier
{
@Override
public boolean verify(String hostname, SSLSession session)
{
return true;
}
}
/**
* 发送代理请求 兼容http以及https
* @param url
* @param param
* @param host
* @param port
* @return 【参数说明】
*
* @return String 【返回类型说明】
* @exception throws 【违例类型】 【违例说明】
* @see 【类、类#方法、类#成员】
*/
public static String sendPostByProxy(String url, String param, String host,
int port, String user, String password)
{
if (StringUtils.isEmpty(url))
{
logger.info("...........请求路径不能为空");
return null;
}
if (url.toLowerCase().startsWith(HTTPS))
{
//HTTPS
return sendHttpsPostByProxy(url, param, host, port, user, password);
}
else if (url.toLowerCase().startsWith(HTTP))
{
//HTTP
return sendHttpPostByProxy(url, param, host, port, user, password);
}
else
{
logger.info(".................请求协议有误");
}
return null;
}
/**
* 用户登录认证
*
* @param user
* @param password
* @param conn
* @return 【参数说明】
*
* @return T 【返回类型说明】
* @exception throws 【违例类型】 【违例说明】
* @see 【类、类#方法、类#成员】
*/
public static
T handleAuth(String user, String password, T conn)
{
if (StringUtils.isEmpty(user) || StringUtils.isEmpty(password))
{
logger.info("............代理用户或者密码为空,不需要用户认证操作");
return conn;
}
String headerkey = "Proxy-Authorization";
String u_p = user + ":" + password;
logger.info(".......代理服务器用户认证信息:" + u_p);
String headerValue = "Basic "
+ Base64.encodeBase64String(u_p.getBytes()); //帐号密码用:隔开,base64加密方式
((URLConnection) conn).setRequestProperty(headerkey, headerValue);
return conn;
}
}
