Java使用代理进行网络连接方法示例
需求是这样的:
一、界面上要有这样几种代理类型可以选。
1.http代理
2.socks代理
3.不使用代理(直连)
4.使用浏览器设置(浏览器也是http、socks、直连三种)。
可参考qq登录设置里的代理能,其实跟qq的代理功能是一样的。
二、测试使用所填写的代理配置信息是否可连接
三、记录用户上次选择的代理配置,默认使用用户上次使用的代理配置进行网络连接。
程序运行环境是windowsxp、windows7、windows8系统。
使用的技术为java7,swing,cxf。
难点:
1.如何进行全居的代理设置:
/** * 网络代理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;// 端口号 private string username;// 代理服务器用户名 private string password;// 代理服务器用户密码 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 + "]"; } }
/** * 根据指定的代理信息设置系统全局的网络代理 * * @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"); } } /** * 网络用户名密码校验提供者 */ 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使用系统的代理:
/** * 为webservice接口添加网络代理支持: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.使用浏览器设置:
/** * 读取用户注册表获取浏览器的代理设置 * * @return 该方法不会返回null值也不会抛出异常 */ 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\"";// 注册表浏览器代理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) {// 从注册表读取失败 e.printstacktrace(); } return networkbean; }
4.测试代理是否可用
因为程序中使用了服务器的两个不同的端口,所以需要测试两个端口是否都可连。
如果使用了多台服务器,更加需要分别测试了。
/** * 测试网络代理是否能通过连接,如果不通过抛出异常 * * @throws exception */ private static void testnetworkproxy() throws exception { testwebservice(); testurlconnection(); } /** * 测试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对象读取指定字符,如果不匹配则抛出异常 * * @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固定返回这个字符串,如果service作了更改此处也应更改 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; } } /** * 测试文件下载接口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); }
/** * 测试代理服务器连接 */ private void testproxyconnection() { networkbean readnetworkbean = networkproxytool.readnetworkbean();// 先获得正在使用的networkbean try { networkbean networkbean = createnetworkbean();// 根据用户填写的信息创建的networkbean对象 showtestresultdialog(networkproxytool.testnetworkproxybysystem(networkbean)); } catch (exception ex) { showtestresultdialog(false); } networkproxytool.setnetworkproxybysystem(readnetworkbean);// 测试结束,还原原来的networkbean }
5.因为java连接网络时,如果使用当前的代理连接失败,那么就会使用操作系统中缓存的代理进行网络连接,如何是测试连接时不使用操作系统缓存,但测试结束后使用操作系统缓存。
/** * 设置长连接和验证信息缓存是否开启 * * @param keepalive */ public static void setkeepaliveandauthcache(boolean keepalive) { system.setproperty("http.keepalive", keepalive + "");// 设置是否开始长连接,如果为false可以防止连接被缓存(如果连接被缓存,用户名密码等所有信息都会被缓存) if (keepalive) { authcachevalue.setauthcache(new authcacheimpl()); } else { // 设置一个空的实现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.保存用户的代理配置:
因为直接序列化自定义类型的对象,会存在版本问题(比如这个类的包名、类名改了,就死定了)。
所以不能直接序列化自定义类的对象,二是将自定义类对象的属性转成字典(map),然后序列化map。
/** * 读取本地网络代理设置配置文件 * * @return */ public static networkbean readnetworkbean() { networkbean networkbean = getcurrnetworkbean(readnetworkbeanmap()); if (networkbean == null) { networkbean = new networkbean(); networkbean.settype(proxy.type.direct); } return networkbean; } /** * 获取用户上次选择网络代理设置 * * @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();
在用户配置完代理点击确定时:
/** * 点击确定 */ 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网络设置有哪些key
java system properties优先级说明
host和port比set优先级高,也就是说set可以不用去设置。
如存在http.proxyhost和http.proxyport时,proxyset设为false无效,系统仍然可以使用http代理。
存在socksproxyhost和socksproxyport时,socksproxyset设为false无效,系统仍然可以使用socks代理。
http比socks优先级高,即存在http.proxyhost和http.proxyport时,socksproxyset、socksproxyhost、socksproxyport都会失效,系统会使用http代理。
使用java.net.proxy
如果只是单个的连接需要使用代理,那么可以采用proxy类进行代理连接。
说明:
1.socket只能使用socks代理不能使用http代理。
2.socket使用使用authenticator来进行验证。
3.urlconnection 使用requestproperty是只对当前连接有效,不会缓存,authenticator是全局性的,对所有网络请求都有效,会缓存,但requestproperty的优先级比authenticator高。
4.只有requestproperty需要64位编码,authenticator不需要。
5.需要清除验证缓存的,不使用验证缓存上面已经有代码了,这里就不重复写了。
6.其实,建议采用全局性的代理连接,不管是urlconnection 还是socket 都简单方便、统一。
代码:
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));
总结
以上就是本文关于java使用代理进行网络连接方法示例的全部内容,希望对大家学习java有所帮助,欢迎各位浏览本站其他专题并随时留言,小编会及时回复大家的。