如果翻過牆,或者做過滲透啥的,肯定對代理不陌生,說白了,代理服務器就是一個中轉站,你對目標網址的請求都會進過代理服務器去請求,類似於一個被你操控的傀儡,別人能知道的也只能是這個代理,從而提升安全性和訪問一些受限制的網站。

實現方式
方法一 :使用系統屬性來完成代理設置, 這種方法比較簡單, 但是不能對單獨的連接來設置代理:
方法二 :使用Proxy來對每個連接實現代理, 這種方法只能在jdk 1.5以上的版本使用(包含jdk1.5), 優點是可以單獨的設置每個連接的代理, 缺點是設置比較麻煩:
先上結果
發送GET請求出現異常! 113.71.209.222 -> 異常
{ip:'113.123.118.129',address:'山東省濱州市 電信'}
{ip:'221.198.63.96',address:'天津市 聯通'}
{ip:'144.255.233.100',address:'山東省 電信'}
{ip:'221.198.63.96',address:'天津市 聯通'}
{ip:'116.2.97.36',address:'遼寧省沈陽市 聯通'}
{ip:'221.198.63.96',address:'天津市 聯通'}
{ip:'221.198.63.96',address:'天津市 聯通'}
{ip:'221.198.63.96',address:'天津市 聯通'}
{ip:'221.198.63.96',address:'天津市 聯通'}
發送GET請求出現異常! 182.91.66.251 -> 異常
{ip:'221.198.63.96',address:'天津市 聯通'}
{ip:'42.6.232.245',address:'遼寧省 聯通'}
發送GET請求出現異常! 27.212.106.212 -> 異常
{ip:'183.158.154.222',address:'浙江省杭州市 電信'}
{ip:'221.198.63.96',address:'天津市 聯通'}
發送GET請求出現異常! 106.113.122.194 -> 異常
{ip:'221.198.63.96',address:'天津市 聯通'}
{ip:'221.198.63.96',address:'天津市 聯通'}
發送GET請求出現異常! 121.225.84.216 -> 異常
發送GET請求出現異常! 111.155.116.232 -> 異常
發送GET請求出現異常! 106.44.81.188 -> 異常
發送GET請求出現異常! 60.187.173.190 -> 異常
{ip:'221.198.63.96',address:'天津市 聯通'}
{ip:'118.80.223.249',address:'山西省陽泉市 聯通'}
發送GET請求出現異常! 119.130.24.74 -> 異常
發送GET請求出現異常! 123.116.57.125 -> 異常
{ip:'221.198.63.96',address:'天津市 聯通'}
{ip:'221.198.63.96',address:'未知國家 '}
發送GET請求出現異常! 171.212.200.237 -> 異常
發送GET請求出現異常! 183.158.154.222 -> 異常
{ip:'139.208.195.31',address:'吉林省延邊州 聯通'}
{ip:'113.140.139.7',address:'陝西省西安市 電信'}
{ip:'123.131.89.41',address:'山東省濰坊市 聯通'}
{ip:'121.41.82.138',address:'浙江省杭州市 阿里雲BGP數據中心'}
發送GET請求出現異常! 116.54.78.99 -> 異常
{ip:'116.234.58.218',address:'上海市 電信'}
{ip:'221.198.63.96',address:'天津市 聯通'}
發送GET請求出現異常! 60.166.89.211 -> 異常
{ip:'221.198.63.96',address:'天津市 聯通'}
{ip:'175.18.57.147',address:'吉林省遼源市 聯通'}
發送GET請求出現異常! 101.28.93.196 -> 異常
{ip:'221.215.190.141',address:'山東省青島市 聯通'}
{ip:'221.198.63.96',address:'天津市 聯通'}
{ip:'221.198.63.96',address:'天津市 聯通'}
{ip:'221.198.63.96',address:'天津市 聯通'}
{ip:'221.198.63.96',address:'天津市 聯通'}
{ip:'171.14.37.251',address:'河南省信陽市 電信'}
{ip:'221.198.63.96',address:'天津市 聯通'}
{ip:'218.78.213.174',address:'上海市 電信'}
{ip:'114.235.80.161',address:'江蘇省徐州市 電信'}
{ip:'221.198.63.96',address:'天津市 聯通'}
{ip:'101.86.86.101',address:'上海市 電信'}
{ip:'221.198.63.96',address:'天津市 聯通'}
{ip:'221.198.63.96',address:'天津市 聯通'}
{ip:'119.187.37.87',address:'山東省 聯通'}
{ip:'221.198.63.96',address:'天津市 聯通'}
{ip:'221.198.63.96',address:'天津市 聯通'}
發送GET請求出現異常! 123.122.150.242 -> 異常
{ip:'221.198.63.96',address:'天津市 聯通'}
發送GET請求出現異常! 175.165.101.48 -> 異常
發送GET請求出現異常! 122.72.32.74 -> 異常
發送GET請求出現異常! 114.237.155.155 -> 異常
{ip:'115.234.155.155',address:'浙江省溫州市 電信'}
發送GET請求出現異常! 121.56.190.52 -> 異常
{ip:'122.236.153.216',address:'浙江省紹興市 電信'}
發送GET請求出現異常! 180.173.109.149 -> 異常
{ip:'221.198.63.96',address:'天津市 聯通'}
{ip:'221.198.63.96',address:'天津市 聯通'}
{ip:'221.198.63.96',address:'天津市 聯通'}
發送GET請求出現異常! 119.182.47.86 -> 異常
{ip:'221.198.63.96',address:'天津市 聯通'}
{ip:'221.198.63.96',address:'天津市 聯通'}
發送GET請求出現異常! 114.217.243.25 -> 異常
發送GET請求出現異常! 117.78.51.231 -> 異常
{ip:'122.97.159.144',address:'江蘇省 聯通'}
{ip:'123.166.23.42',address:'黑龍江省哈爾濱市 電信'}
發送GET請求出現異常! 125.71.133.237 -> 異常
{ip:'114.102.46.16',address:'安徽省馬鞍山市 電信'}
{ip:'1.59.74.243',address:'黑龍江省大慶市 聯通'}
發送GET請求出現異常! 1.61.245.127 -> 異常
{ip:'221.198.63.96',address:'天津市 聯通'}
{ip:'39.64.193.40',address:'山東省 聯通'}
{ip:'221.198.63.96',address:'天津市 聯通'}
{ip:'221.198.63.96',address:'天津市 聯通'}
{ip:'221.198.63.96',address:'天津市 聯通'}
{ip:'221.198.63.96',address:'天津市 聯通'}
{ip:'221.198.63.96',address:'天津市 聯通'}
{ip:'221.198.63.96',address:'黑龍江省七台河市 聯通'}
{ip:'221.198.63.96',address:'天津市 聯通'}
{ip:'221.198.63.96',address:'天津市 聯通'}
{ip:'221.198.63.96',address:'天津市 聯通'}
{ip:'221.198.63.96',address:'天津市 聯通'}
發送GET請求出現異常! 175.172.216.95 -> 異常
{ip:'221.198.63.96',address:'天津市 聯通'}
發送GET請求出現異常! 123.120.219.129 -> 異常
{ip:'111.172.227.239',address:'湖北省武漢市 電信'}
{ip:'221.198.63.96',address:'天津市 聯通'}
{ip:'221.198.63.96',address:'天津市 聯通'}
{ip:'221.198.63.96',address:'天津市 聯通'}
耗時:232.66
國內免費代理的特點是又慢又卡,沒辦法,誰讓人家免費呢,上面出現GET方式請求異常可能有兩個可能
1、超時(我設置了3s超時)
2、代理不能用(這就沒辦法了)
具體實現
方法一 :使用系統屬性來完成代理設置, 這種方法比較簡單, 但是不能對單獨的連接來設置代理:
public static void main(String[] args) {
Properties prop = System.getProperties();
// 設置http訪問要使用的代理服務器的地址
prop.setProperty("http.proxyHost", "192.168.0.254");
// 設置http訪問要使用的代理服務器的端口
prop.setProperty("http.proxyPort", "8080");
// 設置不需要通過代理服務器訪問的主機,可以使用*通配符,多個地址用|分隔
prop.setProperty("http.nonProxyHosts", "localhost|192.168.0.*");
// 設置安全訪問使用的代理服務器地址與端口
// 它沒有https.nonProxyHosts屬性,它按照http.nonProxyHosts 中設置的規則訪問
prop.setProperty("https.proxyHost", "192.168.0.254");
prop.setProperty("https.proxyPort", "443");
// 使用ftp代理服務器的主機、端口以及不需要使用ftp代理服務器的主機
prop.setProperty("ftp.proxyHost", "192.168.0.254");
prop.setProperty("ftp.proxyPort", "2121");
prop.setProperty("ftp.nonProxyHosts", "localhost|192.168.0.*");
// socks代理服務器的地址與端口
prop.setProperty("socksProxyHost", "192.168.0.254");
prop.setProperty("socksProxyPort", "8000");
// 設置登陸到代理服務器的用戶名和密碼
Authenticator.setDefault(new MyAuthenticator("userName", "Password"));
}
static class MyAuthenticator extends Authenticator {
private String user = "";
private String password = "";
public MyAuthenticator(String user, String password) {
this.user = user;
this.password = password;
}
protected PasswordAuthentication getPasswordAuthentication() {
returnnew PasswordAuthentication(user, password.toCharArray());
}
}
別着急,別看到這個就頭大,這是API接口說明
方法二 :使用Proxy來對每個連接實現代理, 這種方法只能在jdk 1.5以上的版本使用(包含jdk1.5), 優點是可以單獨的設置每個連接的代理, 缺點是設置比較麻煩:
public static void main(String[] args) {
try {
URL url = new URL("http://www.baidu.com");
// 創建代理服務器
InetSocketAddress addr = new InetSocketAddress("192.168.0.254",8080);
Proxy proxy = new Proxy(Proxy.Type.HTTP, addr); // http 代理
// 如果我們知道代理server的名字, 可以直接使用
URLConnection conn = url.openConnection(proxy);
InputStream in = conn.getInputStream();
String s = IOUtils.toString(in);
System.out.println(s);
} catch (Exception e) {
e.printStackTrace();
}
}
測試
下面的代碼分別測試了不使用代理,設置全局代理,為單個連接設置代理3中情況。(測試代碼中的代理為網上找的免費代理,比如:http://www.xicidaili.com/,響應速度,穩定性極差),如果代理無響應,java還會自動切換到本地請求。
在上面的結果中有很多的異常,也有很多的本地請求(因為我目前所在地是在天津,切換本地請求就是天津)
注意了:代理服務器ip和端口都不是隨便亂填的,是找的網上免費代理服務器
public static void main(String[] args) throws InterruptedException, IOException {
// 目標網址,會返回發起請求的ip
URL url1 = new URL("http://ip.chinaz.com/getip.aspx");
// 不設置任何代理
String result1 = printInputstream(url1.openStream());
System.out.println(" 不設置任何代理:" + result1);
/**
* 方式一
*/
Properties prop = System.getProperties();
// 設置http訪問要使用的代理服務器的地址
prop.setProperty("http.proxyHost", "120.35.30.178");
// 設置http訪問要使用的代理服務器的端口
prop.setProperty("http.proxyPort", "80");
System.setProperties(prop);
URL url2 = new URL("http://ip.chinaz.com/getip.aspx");
String result2 = printInputstream(url2.openStream());
System.out.println(" 設置全局代理:" + result2);
/**
* 方法二
*/
// 創建代理服務器
InetSocketAddress addr = new InetSocketAddress("220.202.127.78", 8118);
// http 代理
Proxy proxy = new Proxy(Proxy.Type.HTTP, addr);
URL url3 = new URL("http://ip.chinaz.com/getip.aspx");
URLConnection conn = url3.openConnection(proxy);
conn.setReadTimeout(5000);
String result3 = printInputstream(conn.getInputStream());
System.out.println(" 為當前請求設置代理:" + result3);
}
public static String printInputstream(InputStream in) {
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
reader = new BufferedReader(new InputStreamReader(in));
String s = null;
StringBuffer sb = new StringBuffer();
try {
while ((s = reader.readLine()) != null) {
sb.append(s);
}
} catch (IOException e) {
e.printStackTrace();
}
return sb.toString();
}
測試完就會輸出代理服務器的ip和所在地理位置,如果發現不行,那換一個服務器試試,http://www.xicidaili.com/
自動化操作
我們想達到刷訪問量,刷票等需求的時候,不可能手動操作,那樣會累死的,想刷100個訪客或者100張票,那還得等刷到啥時候去了。
我們用http請求訪問免費服務器,雖然有很多不能用,不能用的跳過,我們依然可以有很多的機會,更何況有好幾千個免費代理服務器,況且還不斷刷新,再說了,網上一大堆網站都分享免費服務器,慢歸慢,卡歸卡,但是免費呀,好了,廢話不多說,看代碼。
我們訪問http請求得到相應的網頁信息,但是我們要從中取出ip地址和端口號(得到網頁String-->轉換XML(dom4j)(更方便取)-->取代理服務器ip和端口)
其中用到了dom4j的jar包,maven貼上,
<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>1.6.1</version>
</dependency>
Main.java
package com.xjh.xicidaili;
import com.xjh.demo.proxy.HttpClient;
import com.xjh.utils.HttpUtils;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Created by DIY on 2017/8/2.
*/
public class Main {
private static final String xicidaili = "http://www.xicidaili.com/nn";
public static void main(String args[]) throws IOException, DocumentException {
long startTime = System.currentTimeMillis(); //開始時間
Map<String, String> headProperty = new HashMap<String, String>(); //請求頭
// headProperty.put("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
// headProperty.put("Accept-Encoding", "gzip, deflate, sdch");
// headProperty.put("Accept-Language", "zh-CN,zh;q=0.8");
// headProperty.put("Connection", "keep-alive");
// headProperty.put("Host", "www.xicidaili.com");
// headProperty.put("If-None-Match", "W/\"971e6035d3280dcccdd49aa5a1e1d043\"");
// headProperty.put("Upgrade-Insecure-Requests", "1");
headProperty.put("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.101 Safari/537.36");
Map<String, String> requestProperty = new HashMap<String, String>(); //請求參數
HttpUtils httpUtil = new HttpUtils(xicidaili, headProperty, requestProperty);
httpUtil.setRequestMethod("GET"); //請求方式
HttpUtils.HttpResult xicidailiResult = httpUtil.request(); //同步請求
String xicidailiString = xicidailiResult.getResponseBodyString("UTF-8");
//開始dom4j解析
String table = xicidailiString.substring(xicidailiString.indexOf("<table"), xicidailiString.indexOf("</table>")+8);
table.replaceAll("‹", ""); //去掉非xml字符
Document document = DocumentHelper.parseText(table); //轉換成xml
//===開始從xml中獲得想要的數據===
//獲取xml文件的根節點
Element rootElement=document.getRootElement();
List elements = rootElement.elements(); //得到根節點下所有的子節點
//定義一個Element用於遍歷
Element fooElement;
//遍歷所有名叫“VALUE”的節點
for(int e = 1 ; e<elements.size(); e++){
fooElement=(Element) elements.get(e);
List list = fooElement.elements();
Element addressElement =(Element) list.get(1); //獲得ip地址
Element portElement = (Element)list.get(2); //獲得端口號
try {
HttpClient.httpRequest(addressElement.getText(), portElement.getText());
} catch (Exception e1) {
System.out.println(addressElement.getText() + "\t->\t異常");
}
}
long endTime = System.currentTimeMillis();
System.out.println("耗時:"+ ((double)endTime - (double)startTime)/1000);
}
}
HttpUtils.java(這是個好東西啊)
package com.xjh.utils;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* Http簡單封裝類
* <p>
* 分為同步和異步請求
* <p>
*/
public class HttpUtils {
private static final String TAG = "HttpUtils";
private static final boolean DEBUG = false;
public final static String REQUEST_GET = "GET";
public final static String REQUEST_POST = "POST";
private String mRequestUrl = "";
private String mEncode = "utf-8";
/**
* 是否允許自動跳轉 返回碼為302的時候
*/
private boolean mAllowAutoJump = false;
/**
* 是否取消了異步執行回調
*/
private boolean isCancel = false;
/**
* 請求方式
*/
private String mRequestMethod = REQUEST_GET;
/**
* 響應超時時間
*/
private int mTimeout = 1000 * 3;
/**
* 請求頭參數
*/
private Map<String, String> mHeadProperty = new HashMap<String, String>();
/**
* 請求參數
*/
private Map<String, String> mRequestProperty = new HashMap<String, String>();
public HttpUtils(String requestUrl) {
this(requestUrl, null);
}
public HttpUtils(String requestUrl, Map<String, String> requestProperty) {
this(requestUrl, null, requestProperty);
}
public HttpUtils(String requestUrl, Map<String, String> headProperty, Map<String, String> requestProperty) {
this.mRequestUrl = requestUrl;
this.mHeadProperty = headProperty;
this.mRequestProperty = requestProperty;
}
/**
* 設置請求的URL
*/
public HttpUtils setRequestUrl(String url) {
this.mRequestUrl = url;
return this;
}
/**
* 設置請求模式
*
* @param requestMethod {@link #REQUEST_GET} {{@link #REQUEST_POST}}
*/
public HttpUtils setRequestMethod(String requestMethod) {
this.mRequestMethod = requestMethod;
return this;
}
/**
* 設置是否自動跳轉,自動響應302等
*
* @param allow
* @return
*/
public HttpUtils setAllowAutoJump(boolean allow) {
mAllowAutoJump = allow;
return this;
}
/**
* 設置請求頭
*/
public HttpUtils setHeadProperty(Map<String, String> headProperty) {
this.mHeadProperty = headProperty;
return this;
}
/**
* 添加請求頭參數
*/
public HttpUtils addHeadProperty(String key, String value) {
this.mHeadProperty.put(key, value);
return this;
}
/**
* 設置請求參數
*/
public HttpUtils setRequestProperty(Map<String, String> requestProperty) {
this.mRequestProperty = requestProperty;
return this;
}
/**
* 添加請求參數
*/
public HttpUtils addRequestProperty(String key, String value) {
this.mRequestProperty.put(key, value);
return this;
}
/**
* 設置超時時間
*/
public HttpUtils setTimeout(int timeout) {
this.mTimeout = timeout;
return this;
}
/**
* 設置參數編碼格式
*
* @param encoder 默認編碼為utf-8
* @return
*/
public HttpUtils setRequestEncoder(String encoder) {
mEncode = encoder;
return this;
}
/**
* 同步請求
*/
public HttpResult request() {
return doRequest();
}
/**
* 取消異步請求
*/
public void cancelSync() {
isCancel = true;
}
/**
* 發出異步請求
*/
public void requestSync(final HttpCallBack callBack) {
isCancel = false;
new Thread(new Runnable() {
@Override
public void run() {
HttpResult httpResult = doRequest();
//如果已經被取消掉了或者回調設置為空,則直接退出
if (isCancel || callBack == null) {
return;
}
if (httpResult.getException() != null) {
callBack.onError(httpResult.getException());
} else {
callBack.onSuccess(httpResult);
}
callBack.onComplete();
}
}).start();
}
/**
* 在請求之前允許對請求進行處理
*
* @param headProperty 設置的請求頭 可能為null
* @param requestProperty 設置的參數 可能為null
*/
protected void perRequest(Map<String, String> headProperty, Map<String, String> requestProperty) {
}
/**
* 允許對響應結果進行處理
*/
protected void afterRequest(HttpResult httpResult) {
}
/**
* 真正執行網絡請求的位置
*/
private HttpResult doRequest() {
HttpResult httpResult = new HttpResult();
try {
//去掉網址結尾的 /分號
mRequestUrl.replaceAll("/*$", "");
perRequest(mHeadProperty, mRequestProperty);
URL url;
//請求參數格式化結果
String requestString = formatProperty(mRequestProperty);
if (REQUEST_GET.equals(mRequestMethod)) {
if ("".equals(requestString)) {
url = new URL(mRequestUrl);
} else {
url = new URL(mRequestUrl + "?" + requestString);
}
} else {
url = new URL(mRequestUrl);
}
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod(mRequestMethod);
conn.setConnectTimeout(mTimeout);
conn.setReadTimeout(mTimeout);
conn.setInstanceFollowRedirects(mAllowAutoJump);
// conn.setAllowUserInteraction(mAllowAutoJump);
//設置請求頭
if (mHeadProperty != null) {
Set<Map.Entry<String, String>> entries = mHeadProperty.entrySet();
for (Map.Entry<String, String> entry : entries) {
String key = entry.getKey();
String value = entry.getValue();
conn.setRequestProperty(key, value);
}
}
//設置參數
if (REQUEST_POST.equals(mRequestMethod)) {
conn.setDoOutput(true);
OutputStream outputStream = conn.getOutputStream();
outputStream.write(requestString.getBytes(mEncode));
}
InputStream in = conn.getInputStream();
byte[] responseBytes = inputStream2Bytes(in);
httpResult.setResponseCode(conn.getResponseCode());
httpResult.setResponseHead(conn.getHeaderFields());
httpResult.setResponseBody(responseBytes);
} catch (Exception e) {
httpResult.setException(e);
}
afterRequest(httpResult);
return httpResult;
}
/**
* 格式化參數
* <p>
* 類似於pws=123&uid=123的形式
*/
private String formatProperty(Map<String, String> property) {
StringBuilder formatResult = new StringBuilder();
if (property == null) {
return formatResult.toString();
}
Set<Map.Entry<String, String>> entries = property.entrySet();
int begin = 0;
//拼接所有參數
for (Map.Entry<String, String> entry : entries) {
String key = entry.getKey();
String value = entry.getValue();
if (begin == 0) {
begin++;
} else {
formatResult.append("&");
}
formatResult.append(key);
formatResult.append("=");
formatResult.append(value);
}
return formatResult.toString();
}
/**
* 將輸出流讀取為字符串
*
* @param in 輸出流
* @param charsetName 讀取的編碼格式
* @return
* @throws IOException
*/
private String inputStream2String(InputStream in, String charsetName) throws IOException {
StringBuffer result = new StringBuffer();
BufferedReader reader = new BufferedReader(new InputStreamReader(in, charsetName));
String temp;
while ((temp = reader.readLine()) != null) {
result.append(temp);
}
in.close();
return result.toString();
}
/**
* 將輸入流裝換為byte數組
*
* @param in 輸入流
* @return
* @throws IOException
*/
private byte[] inputStream2Bytes(InputStream in) throws IOException {
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len = 0;
while ((len = in.read(buffer)) != -1) {
outStream.write(buffer, 0, len);
}
in.close();
return outStream.toByteArray();
}
/**
* Http請求響應結果包裝類
*/
public static final class HttpResult {
private int mResponseCode;
private Map<String, List<String>> mResponseHead;
private byte[] mResponseBody;
private Exception exception;
public int getResponseCode() {
return mResponseCode;
}
public void setResponseCode(int responseCode) {
this.mResponseCode = responseCode;
}
public Map<String, List<String>> getResponseHead() {
return mResponseHead;
}
public void setResponseHead(Map<String, List<String>> responseHead) {
this.mResponseHead = responseHead;
}
public byte[] getResponseBody() {
return mResponseBody;
}
public String getResponseBodyString(String charset) {
try {
return new String(getResponseBody(), charset);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return "";
}
public void setResponseBody(byte[] responseBody) {
this.mResponseBody = responseBody;
}
public Exception getException() {
return exception;
}
public void setException(Exception exception) {
this.exception = exception;
}
@Override
public String toString() {
return "HttpResult{" +
"mResponseCode=" + mResponseCode +
", mResponseHead=" + mResponseHead +
", mResponseBody=" + Arrays.toString(mResponseBody) +
", exception=" + exception +
'}';
}
}
/**
* Http響應回調
*/
public interface HttpCallBack {
void onError(Exception e);
void onSuccess(HttpResult httpResult);
void onComplete();
}
}
HttpClient.java
package com.xjh.demo.proxy;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.URL;
import java.net.URLConnection;
import java.util.List;
import java.util.Map;
import java.util.Properties;
/**
* Created by DIY on 2017/8/2.
*/
public class HttpClient {
public static void httpRequest(String address, String port) throws Exception {
// 如果不設置,只要代理IP和代理端口正確,此項不設置也可以
// System.getProperties().setProperty("http.proxyHost", "10.22.40.32");
// System.getProperties().setProperty("http.proxyPort", "8080");
Properties prop = System.getProperties();
prop.setProperty("http.proxyHost", address);
prop.setProperty("http.proxyPort", port);
System.setProperties(prop);
// URL url2 = new URL("http://ip.chinaz.com/getip.aspx");
// String result2 = printInputstream(url2.openStream());
// System.out.println(" 設置全局代理:" + result2);
// 判斷代理是否設置成功
// 發送 GET 請求
System.out.println(sendGet(
"http://ip.chinaz.com/getip.aspx",
""));
// 發送 POST 請求
}
/**
* 向指定URL發送GET方法的請求
*
* @param url
* 發送請求的URL
* @param param
* 請求參數,請求參數應該是 name1=value1&name2=value2 的形式。
* @return URL 所代表遠程資源的響應結果
*/
public static String sendGet(String url, String param) {
String result = "";
BufferedReader in = null;
try {
String urlNameString = url + "?" + param;
URL realUrl = new URL(urlNameString);
// 打開和URL之間的連接
URLConnection connection = realUrl.openConnection();
connection.setConnectTimeout(3000);
connection.setReadTimeout(3000);
// 設置通用的請求屬性
connection.setRequestProperty("accept", "*/*");
connection.setRequestProperty("connection", "Keep-Alive");
connection.setRequestProperty("user-agent",
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
// 建立實際的連接
connection.connect();
// 獲取所有響應頭字段
Map<String, List<String>> map = connection.getHeaderFields();
// 遍歷所有的響應頭字段
for (String key : map.keySet()) {
// System.out.println(key + "--->" + map.get(key));
}
// 定義 BufferedReader輸入流來讀取URL的響應
in = new BufferedReader(new InputStreamReader(
connection.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
result += line;
}
} catch (Exception e) {
System.out.print("發送GET請求出現異常!\t");
throw new RuntimeException("錯誤+1");
}
// 使用finally塊來關閉輸入流
finally {
try {
if (in != null) {
in.close();
}
} catch (Exception e2) {
e2.printStackTrace();
}
}
return result;
}
/**
* 向指定 URL 發送POST方法的請求
*
* @param url
* 發送請求的 URL
* @param param
* 請求參數,請求參數應該是 name1=value1&name2=value2 的形式。
* @return 所代表遠程資源的響應結果
*/
public static String sendPost(String url, String param) {
PrintWriter out = null;
BufferedReader in = null;
String result = "";
try {
URL realUrl = new URL(url);
// 打開和URL之間的連接
URLConnection conn = realUrl.openConnection();
// 設置通用的請求屬性
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);
// 獲取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;
}
} 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;
}
}
通過這樣的操作,我們還不夠,一個線程的力量是微小的,我們用多線程,分發線程,循環漸漸,我們想要的目的就達到了。
再或者我們可以用定時調度,有以下幾種主要技術
1、Java自帶的java.util.Timer類,這個類允許你調度一個java.util.TimerTask任務;
2、Quartz;
3、Spring3.0以后自帶的task。
在每天定點定時的去訪問我們的線程,這樣我們可以完全放手讓程序自己去跑,我們只需要偶爾看看它完成的好不好就ok的,這樣服務器也會稍微輕松一點,這樣也比較鍛煉我們的技術與能力。
如果想關注spring的定時調度,請關注我的下一篇博文。
積木搭起的房子看似很美,
卻會在不經意間轟然倒塌。
