需求是这样的:

一、界面上要有这样几种代理类型可以选。
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
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优先级说明
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有所帮助,欢迎各位浏览本站其他专题并随时留言,小编会及时回复大家的。
# java
# 使用代理连接
# 网络连接
# 浅谈Java注解和动态代理
# JAVA中的静态代理、动态代理以及CGLIB动态代理总结
# Java动态代理实现_动力节点Java学院整理
# java设计模式之代理模式(Porxy)详解
# java 1.8 动态代理源码深度分析
# 自定义
# 代理服务器
# 注册表
# 抛出
# 设为
# 操作系统
# 可以使用
# 序列化
# 可以防止
# 就会
# 使用了
# 运行环境
# 浏览器设置
# 不需要
# 是这样
# 就不
# 要有
# 作了
# 三种
# 写了
相关文章:
建站主机SSH密钥生成步骤及常见问题解答?
Avalonia如何实现跨窗口通信 Avalonia窗口间数据传递
详解免费开源的DotNet二维码操作组件ThoughtWorks.QRCode(.NET组件介绍之四)
实例解析Array和String方法
Swift中循环语句中的转移语句 break 和 continue
电脑免费海报制作网站推荐,招聘海报哪个网站多?
建站之星安装需要哪些步骤及注意事项?
公司网站建设制作费用,想建设一个属于自己的企业网站,该如何去做?
济南企业网站制作公司,济南社保单位网上缴费步骤?
东莞专业网站制作公司有哪些,东莞招聘网站哪个好?
企业网站制作公司网页,推荐几家专业的天津网站制作公司?
如何通过虚拟主机快速完成网站搭建?
如何快速搭建高效香港服务器网站?
建站一年半SEO优化实战指南:核心词挖掘与长尾流量提升策略
如何通过PHP快速构建高效问答网站功能?
北京的网站制作公司有哪些,哪个视频网站最好?
制作国外网站的软件,国外有哪些比较优质的网站推荐?
岳西云建站教程与模板下载_一站式快速建站系统操作指南
建站之星各版本价格是多少?
如何在局域网内绑定自建网站域名?
Python路径拼接规范_跨平台处理说明【指导】
建站主机选购指南:核心配置优化与品牌推荐方案
c++怎么用jemalloc c++替换默认内存分配器【性能】
宝塔建站无法访问?如何排查配置与端口问题?
如何在Golang中实现微服务服务拆分_Golang微服务拆分与接口管理方法
高配服务器限时抢购:企业级配置与回收服务一站式优惠方案
免费的流程图制作网站有哪些,2025年教师初级职称申报网上流程?
制作电商网页,电商供应链怎么做?
小捣蛋自助建站系统:数据分析与安全设置双核驱动网站优化
在线制作视频的网站有哪些,电脑如何制作视频短片?
广州建站公司哪家好?十大优质服务商推荐
网站制作多少钱一个,建一个论坛网站大约需要多少钱?
临沂网站制作公司有哪些,临沂第四中学官网?
购物网站制作公司有哪些,哪个购物网站比较好?
深圳 网站制作,深圳招聘网站哪个比较好一点啊?
建站主机是什么?如何选择适合的建站主机?
,柠檬视频怎样兑换vip?
建站之星五站合一营销型网站搭建攻略,流量入口全覆盖优化指南
建站之星安装后如何配置SEO及设计样式?
如何在景安服务器上快速搭建个人网站?
建站主机类型有哪些?如何正确选型
简易网站制作视频教程,使用记事本编写一个简单的网页html文件?
C#怎么使用委托和事件 C# delegate与event编程方法
相册网站制作软件,图片上的网址怎么复制?
如何打造高效商业网站?建站目的决定转化率
网站制作的软件有哪些,制作微信公众号除了秀米还有哪些比较好用的平台?
c# 服务器GC和工作站GC的区别和设置
如何通过智能用户系统一键生成高效建站方案?
成都品牌网站制作公司,成都营业执照年报网上怎么办理?
建站之星免费模板:自助建站系统与智能响应式一键生成
*请认真填写需求信息,我们会在24小时内与您取得联系。