在Java中怎么利用代理對(duì)網(wǎng)絡(luò)進(jìn)行連接?很多新手對(duì)此不是很清楚,為了幫助大家解決這個(gè)難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來學(xué)習(xí)下,希望你能有所收獲。
始興ssl適用于網(wǎng)站、小程序/APP、API接口等需要進(jìn)行數(shù)據(jù)傳輸應(yīng)用場(chǎng)景,ssl證書未來市場(chǎng)廣闊!成為創(chuàng)新互聯(lián)公司的ssl證書銷售渠道,可以享受市場(chǎng)價(jià)格4-6折優(yōu)惠!如果有意向歡迎電話聯(lián)系或者加微信:18980820575(備注:SSL證書合作)期待與您的合作!
需求是這樣的:
一、界面上要有這樣幾種代理類型可以選。
1.HTTP代理
2.Socks代理
3.不使用代理(直連)
4.使用瀏覽器設(shè)置(瀏覽器也是HTTP、Socks、直連三種)。
可參考QQ登錄設(shè)置里的代理能,其實(shí)跟qq的代理功能是一樣的。
二、測(cè)試使用所填寫的代理配置信息是否可連接
三、記錄用戶上次選擇的代理配置,默認(rèn)使用用戶上次使用的代理配置進(jìn)行網(wǎng)絡(luò)連接。
程序運(yùn)行環(huán)境是WindowsXP、Windows7、Windows8系統(tǒng)。
使用的技術(shù)為Java7,Swing,CXF。
難點(diǎn):
1.如何進(jìn)行全居的代理設(shè)置:
/** * 網(wǎng)絡(luò)代理Bean * * @author tang */ public class NetworkBean implements Serializable { private static final long serialVersionUID = 1L; // private static sun.misc.BASE64Encoder base64Encoder = new sun.misc.BASE64Encoder(); private Proxy.Type type;// 代理類型 private String address;// ip 地址 private String port;// 端口號(hào) private String username;// 代理服務(wù)器用戶名 private String password;// 代理服務(wù)器用戶密碼 private String domain;// 域 private String typeText;// 代理類型顯示的文本 public NetworkBean() { } public NetworkBean(Type type, String address, String port, String username, String password) { this.type = type; this.address = address; this.port = port; this.username = username; this.password = password; } public NetworkBean(Type type, String address, String port, String username, String password, String domain) { super(); this.type = type; this.address = address; this.port = port; this.username = username; this.password = password; this.domain = domain; } public Proxy.Type getType() { return type; } public void setType(Proxy.Type type) { this.type = type; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } public String getPort() { return port; } public void setPort(String port) { this.port = port; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getDomain() { return domain; } public void setDomain(String domain) { this.domain = domain; } public String getTypeText() { return typeText; } public void setTypeText(String typeText) { this.typeText = typeText; } /** * return domain + "\" + username */ public String getDomainAndUsername() { return (Utils.toString(domain).trim().isEmpty()) ? username : domain.trim() + "\\" + username; } /** * return domain + "\" + username + ":" + password */ public String getDomainAndUsernameAndPassword() { return getDomainAndUsername() + ":" + password; } /** * return username + ":" + password */ public String getUsernameAndPassword() { return username + ":" + password; } /** * return (domain + "\" + username + ":" + password) to 64 bit */ public String getDomainAndUsernameAndPassword64() { return org.apache.commons.codec.binary.Base64.encodeBase64String(getDomainAndUsernameAndPassword().getBytes()); } @Override public String toString() { return "NetworkBean [type=" + type + ", typeText=" + typeText + ", address=" + address + ", port=" + port + ", username=" + username + ", password=" + password + ", domain=" + domain + "]"; } }
/** * 根據(jù)指定的代理信息設(shè)置系統(tǒng)全局的網(wǎng)絡(luò)代理 * * @param networkBean */ public static void setNetworkProxyBySystem(NetworkBean networkBean) { System.out.println("System Set Proxy : " + networkBean); if (isUserProxy(networkBean)) { if (networkBean.getType() == Proxy.Type.SOCKS) { System.getProperties().remove("http.proxyHost"); System.getProperties().remove("http.proxyPort"); System.getProperties().setProperty("socksProxyHost", networkBean.getAddress()); System.getProperties().setProperty("socksProxyPort", networkBean.getPort()); } else { System.getProperties().setProperty("http.proxyHost", networkBean.getAddress()); System.getProperties().setProperty("http.proxyPort", networkBean.getPort()); } Authenticator.setDefault(new BairuiAuthenticator(networkBean.getDomainAndUsername(), networkBean.getPassword())); } else if (networkBean != null) { System.getProperties().remove("proxySet"); System.getProperties().remove("socksProxySet"); System.getProperties().remove("http.proxyHost"); System.getProperties().remove("http.proxyPort"); System.getProperties().remove("socksProxyHost"); System.getProperties().remove("socksProxyPort"); } } /** * 網(wǎng)絡(luò)用戶名密碼校驗(yàn)提供者 */ public static class BairuiAuthenticator extends Authenticator { private String username, password; public BairuiAuthenticator(String username, String password) { this.username = username; this.password = password; } protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(username, password == null ? null : password.toCharArray()); } }
2.如何讓CXF的Service使用系統(tǒng)的代理:
/** * 為WebService接口添加網(wǎng)絡(luò)代理支持:httpClientPolicy.setAllowChunking(false); * * @param client */ public static void setWebServiceSupportProxy(Client client) { HTTPConduit conduit = (HTTPConduit) client.getConduit(); HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy(); httpClientPolicy.setAllowChunking(false); conduit.setClient(httpClientPolicy); }
3.使用瀏覽器設(shè)置:
/** * 讀取用戶注冊(cè)表獲取瀏覽器的代理設(shè)置 * * @return 該方法不會(huì)返回null值也不會(huì)拋出異常 */ public static NetworkBean getBrowserProxy() { NetworkBean networkBean = new NetworkBean(); networkBean.setTypeText(typeTexts[3]); networkBean.setType(Proxy.Type.DIRECT); String key = "reg query \"HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\"";// 注冊(cè)表瀏覽器代理key try { Process exec = Runtime.getRuntime().exec(key); try (InputStreamReader i = new InputStreamReader(exec.getInputStream()); BufferedReader ir = new BufferedReader(i)) { for (String line = ir.readLine(); line != null; line = ir.readLine()) { if (line.indexOf("ProxyServer") >= 0) { String[] split1 = line.split(" "); if (split1.length > 3) { String[] split2 = split1[3].trim().split(":"); if (split2.length > 1) { if (!Utils.toString(split2[0]).isEmpty() && !Utils.toString(split2[1]).isEmpty()) { networkBean.setAddress(split2[0]); networkBean.setPort(split2[1]); networkBean.setType(Proxy.Type.HTTP); break; } } } } } } catch (Exception e) { e.printStackTrace(); } } catch (Exception e) {// 從注冊(cè)表讀取失敗 e.printStackTrace(); } return networkBean; }
4.測(cè)試代理是否可用
因?yàn)槌绦蛑惺褂昧朔?wù)器的兩個(gè)不同的端口,所以需要測(cè)試兩個(gè)端口是否都可連。
如果使用了多臺(tái)服務(wù)器,更加需要分別測(cè)試了。
/** * 測(cè)試網(wǎng)絡(luò)代理是否能通過連接,如果不通過拋出異常 * * @throws Exception */ private static void testNetworkProxy() throws Exception { testWebService(); testURLConnection(); } /** * 測(cè)試CXF Service接口50367端口 * * @param networkBean * @throws Exception */ public static void testWebService() throws Exception { JcptLoginService service = WebServiceUtils.getService(JcptLoginService.class, GeneralWebServiceAddress.LOGIN_SERVICE_URL_ADD); String result = service.getLoginPicture(); System.out.println(result); } /** * 從HttpURLConnection對(duì)象讀取指定字符,如果不匹配則拋出異常 * * @param connection * @throws Exception */ private static void checkConnectionContent(HttpURLConnection connection) throws Exception { try (InputStream inputStream = connection.getInputStream()) { byte[] b = new byte[1024]; boolean success = false; StringBuffer sb = new StringBuffer(); for (int i = inputStream.read(b); i > 0; i = inputStream.read(b)) { String tempStr = new String(b, 0, i); sb.append(tempStr); if (tempStr.indexOf("3,file not found") >= 0) {// service固定返回這個(gè)字符串,如果service作了更改此處也應(yīng)更改 success = true; break; } } if (!success) { String str = sb.toString(); if (str.length() > 3) { char char0 = str.charAt(0); char char1 = str.charAt(1); if (Utils.isNumber(char0 + "") && char1 == ',') { success = true; } } } if (!success) { throw new RuntimeException("result content does not meet expectations."); } } catch (Exception ex) { throw ex; } } /** * 測(cè)試文件下載接口9067端口 * * @param networkBean * @throws Exception */ public static void testURLConnection() throws Exception { HttpURLConnection connection = (HttpURLConnection) new URL(GeneralWebServiceAddress.FILE_DOWN_URL_ADD + "path=").openConnection(); checkConnectionContent(connection); }
/** * 測(cè)試代理服務(wù)器連接 */ private void testProxyConnection() { NetworkBean readNetworkBean = NetworkProxyTool.readNetworkBean();// 先獲得正在使用的NetworkBean try { NetworkBean networkBean = createNetworkBean();// 根據(jù)用戶填寫的信息創(chuàng)建的NetworkBean對(duì)象 showTestResultDialog(NetworkProxyTool.testNetworkProxyBySystem(networkBean)); } catch (Exception ex) { showTestResultDialog(false); } NetworkProxyTool.setNetworkProxyBySystem(readNetworkBean);// 測(cè)試結(jié)束,還原原來的NetworkBean }
5.因?yàn)閖ava連接網(wǎng)絡(luò)時(shí),如果使用當(dāng)前的代理連接失敗,那么就會(huì)使用操作系統(tǒng)中緩存的代理進(jìn)行網(wǎng)絡(luò)連接,如何是測(cè)試連接時(shí)不使用操作系統(tǒng)緩存,但測(cè)試結(jié)束后使用操作系統(tǒng)緩存。
/** * 設(shè)置長(zhǎng)連接和驗(yàn)證信息緩存是否開啟 * * @param keepAlive */ public static void setKeepAliveAndAuthCache(boolean keepAlive) { System.setProperty("http.keepAlive", keepAlive + "");// 設(shè)置是否開始長(zhǎng)連接,如果為false可以防止連接被緩存(如果連接被緩存,用戶名密碼等所有信息都會(huì)被緩存) if (keepAlive) { AuthCacheValue.setAuthCache(new AuthCacheImpl()); } else { // 設(shè)置一個(gè)空的實(shí)現(xiàn)AuthCache可以防止用戶名密碼信息被緩存 AuthCacheValue.setAuthCache(new AuthCache() { public void remove(String pkey, AuthCacheValue entry) { } public void put(String pkey, AuthCacheValue value) { } public AuthCacheValue get(String pkey, String skey) { return null; } }); } }
在登錄之前:
NetworkProxyTool.setKeepAliveAndAuthCache(false); new.Login();
登錄成功后:
NetworkProxyTool.setKeepAliveAndAuthCache(true);
6.保存用戶的代理配置:
因?yàn)橹苯有蛄谢远x類型的對(duì)象,會(huì)存在版本問題(比如這個(gè)類的包名、類名改了,就死定了)。
所以不能直接序列化自定義類的對(duì)象,二是將自定義類對(duì)象的屬性轉(zhuǎn)成字典(Map),然后序列化map。
/** * 讀取本地網(wǎng)絡(luò)代理設(shè)置配置文件 * * @return */ public static NetworkBean readNetworkBean() { NetworkBean networkBean = getCurrNetworkBean(readNetworkBeanMap()); if (networkBean == null) { networkBean = new NetworkBean(); networkBean.setType(Proxy.Type.DIRECT); } return networkBean; } /** * 獲取用戶上次選擇網(wǎng)絡(luò)代理設(shè)置 * * @param map * @return */ public static NetworkBean getCurrNetworkBean(Map<String, Object> map) { putBrowserProxy(map); return (NetworkBean) map.get(getTypeMapKey(map)); } /** * 將瀏覽器的信息存放入代理信息總配置map * * @param map */ private static void putBrowserProxy(Map<String, Object> map) { if (browserProxyBean == null) { browserProxyBean = getBrowserProxy(); } NetworkBean networkBeanBrowser = (NetworkBean) map.get(key_browser); if (networkBeanBrowser == null) { networkBeanBrowser = browserProxyBean; } if ((Utils.toString(browserProxyBean.getAddress()).isEmpty() || !browserProxyBean.getAddress().equals(networkBeanBrowser.getAddress())) || (Utils.toString(browserProxyBean.getPort()).isEmpty() || !browserProxyBean.getPort().equals(networkBeanBrowser.getPort()))) { networkBeanBrowser.setUsername(null); networkBeanBrowser.setPassword(null); networkBeanBrowser.setDomain(null); } networkBeanBrowser.setType(browserProxyBean.getType()); networkBeanBrowser.setTypeText(browserProxyBean.getTypeText()); networkBeanBrowser.setAddress(browserProxyBean.getAddress()); networkBeanBrowser.setPort(browserProxyBean.getPort()); map.put(key_browser, networkBeanBrowser); }
在登錄之前:
NetworkBean networkBean = NetworkProxyTool.readNetworkBean(); NetworkProxyTool.setNetworkProxyBySystem(networkBean); NetworkProxyTool.setKeepAliveAndAuthCache(false); new.Login();
在用戶配置完代理點(diǎn)擊確定時(shí):
/** * 點(diǎn)擊確定 */ private void confirm() { if ((isHttp() || isSocks()) && !checkIpAndPortNotNull()) { return; } NetworkBean networkBean = createNetworkBean(); if (isHttp()) {// HTTP代理 if (networkBean.getDomain() != null) { networkBean.setDomain(networkBean.getDomain().trim()); } proxySettingMap.put(key_http, networkBean); proxySettingMap.put(key_proxy_type, key_http); } else if (isSocks()) {// SOCKS代理 proxySettingMap.put(key_socks, networkBean); proxySettingMap.put(key_proxy_type, key_socks); } else if (isBrowser()) { proxySettingMap.put(key_browser, networkBean); proxySettingMap.put(key_proxy_type, key_browser); } else { proxySettingMap.put(key_direct, networkBean); proxySettingMap.put(key_proxy_type, key_direct); } userCurrShowNetworkBean = networkBean; isConfirm = true; setVisible(false); NetworkProxyTool.saveNetworkProxyConfig(proxySettingMap); }
System Properties
Java System Properties網(wǎng)絡(luò)設(shè)置有哪些key
http://docs.oracle.com/javase/7/docs/technotes/guides/net/properties.html
http://docs.oracle.com/javase/7/docs/api/java/net/doc-files/net-properties.html
Java System Properties優(yōu)先級(jí)說明
host和port比set優(yōu)先級(jí)高,也就是說set可以不用去設(shè)置。
如存在http.proxyHost和http.proxyPort時(shí),proxySet設(shè)為false無效,系統(tǒng)仍然可以使用http代理。
存在socksProxyHost和socksProxyPort時(shí),socksProxySet設(shè)為false無效,系統(tǒng)仍然可以使用socks代理。
http比socks優(yōu)先級(jí)高,即存在http.proxyHost和http.proxyPort時(shí),socksProxySet、socksProxyHost、socksProxyPort都會(huì)失效,系統(tǒng)會(huì)使用http代理。
使用java.net.Proxy
如果只是單個(gè)的連接需要使用代理,那么可以采用Proxy類進(jìn)行代理連接。
說明:
1.Socket只能使用socks代理不能使用http代理。
2.Socket使用使用Authenticator來進(jìn)行驗(yàn)證。
3.URLConnection 使用RequestProperty是只對(duì)當(dāng)前連接有效,不會(huì)緩存,Authenticator是全局性的,對(duì)所有網(wǎng)絡(luò)請(qǐng)求都有效,會(huì)緩存,但RequestProperty的優(yōu)先級(jí)比Authenticator高。
4.只有RequestProperty需要64位編碼,Authenticator不需要。
5.需要清除驗(yàn)證緩存的,不使用驗(yàn)證緩存上面已經(jīng)有代碼了,這里就不重復(fù)寫了。
6.其實(shí),建議采用全局性的代理連接,不管是URLConnection 還是Socket 都簡(jiǎn)單方便、統(tǒng)一。
代碼:
NetworkBean httpBean = new NetworkBean(Proxy.Type.HTTP, "192.168.77.5", "8888", "tzc", "123", null); Proxy httpProxy = new Proxy(httpBean.getType(), new InetSocketAddress(httpBean.getAddress(), Integer.parseInt(httpBean.getPort()))); NetworkBean socksBean = new NetworkBean(Proxy.Type.SOCKS, "192.168.77.5", "9999", "tzc", "123", "ttt"); Proxy socksProxy = new Proxy(socksBean.getType(), new InetSocketAddress(socksBean.getAddress(), Integer.parseInt(socksBean.getPort()))); URLConnection httpProxyConnection = new URL("http://www.baidu.com/").openConnection(httpProxy); //或者Authenticator.setDefault(new BairuiAuthenticator(networkBean.getDomainAndUsername(), networkBean.getPassword())); httpProxyConnection.setRequestProperty("Proxy-Authorization", "Basic "+httpBean.getDomainAndUsernameAndPassword64()); URLConnection socksProxyConnection = new URL("http://www.baidu.com/").openConnection(socksProxy); //或者Authenticator.setDefault(new BairuiAuthenticator(networkBean.getDomainAndUsername(), networkBean.getPassword())); socksProxyConnection.setRequestProperty("Proxy-Authorization", "Basic "+httpBean.getDomainAndUsernameAndPassword64()); Socket socket = new Socket(socksProxy); Authenticator.setDefault(new BairuiAuthenticator(networkBean.getDomainAndUsername(), networkBean.getPassword())); socket.connect(new InetSocketAddress("www.baidu.com", 5555));
看完上述內(nèi)容是否對(duì)您有幫助呢?如果還想對(duì)相關(guān)知識(shí)有進(jìn)一步的了解或閱讀更多相關(guān)文章,請(qǐng)關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝您對(duì)創(chuàng)新互聯(lián)的支持。
分享文章:在Java中怎么利用代理對(duì)網(wǎng)絡(luò)進(jìn)行連接
鏈接分享:http://www.rwnh.cn/article6/igpoig.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供自適應(yīng)網(wǎng)站、域名注冊(cè)、搜索引擎優(yōu)化、企業(yè)建站、品牌網(wǎng)站制作、外貿(mào)網(wǎng)站建設(shè)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)