Java使用代理进行网络连接方法示例

2025-05-29 0 61

需求是这样的:

一、界面上要有这样几种代理类型可以选。

1.HTTP代理

2.Socks代理

3.不使用代理(直连)

4.使用浏览器设置(浏览器也是HTTP、Socks、直连三种)。

可参考QQ登录设置里的代理能,其实跟qq的代理功能是一样的。

二、测试使用所填写的代理配置信息是否可连接

三、记录用户上次选择的代理配置,默认使用用户上次使用的代理配置进行网络连接

程序运行环境是WindowsXP、Windows7、Windows8系统。

使用的技术为Java7,Swing,CXF。

难点:

1.如何进行全居的代理设置:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105
/**

* 网络代理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 + "]";

}

}

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40
/**

* 根据指定的代理信息设置系统全局的网络代理

*

* @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使用系统的代理

?

1

2

3

4

5

6

7

8

9

10

11
/**

* 为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.使用浏览器设置:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37
/**

* 读取用户注册表获取浏览器的代理设置

*

* @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.测试代理是否可用

因为程序中使用了服务器的两个不同的端口,所以需要测试两个端口是否都可连。

如果使用了多台服务器,更加需要分别测试了。

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66
/**

* 测试网络代理是否能通过连接,如果不通过抛出异常

*

* @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);

}

?

1

2

3

4

5

6

7

8

9

10

11

12

13
/**

* 测试代理服务器连接

*/

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连接网络时,如果使用当前的代理连接失败,那么就会使用操作系统中缓存的代理进行网络连接,如何是测试连接时不使用操作系统缓存,但测试结束后使用操作系统缓存。

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22
/**

* 设置长连接和验证信息缓存是否开启

*

* @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;

}

});

}

}

在登录之前:

?

1

2
NetworkProxyTool.setKeepAliveAndAuthCache(false);

new.Login();

登录成功后:

?

1
NetworkProxyTool.setKeepAliveAndAuthCache(true);

6.保存用户的代理配置:

因为直接序列化自定义类型的对象,会存在版本问题(比如这个类的包名、类名改了,就死定了)。
所以不能直接序列化自定义类的对象,二是将自定义类对象的属性转成字典(Map),然后序列化map。

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48
/**

* 读取本地网络代理设置配置文件

*

* @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);

}

在登录之前:

?

1

2

3

4
NetworkBean networkBean = NetworkProxyTool.readNetworkBean();

NetworkProxyTool.setNetworkProxyBySystem(networkBean);

NetworkProxyTool.setKeepAliveAndAuthCache(false);

new.Login();

在用户配置完代理点击确定时:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30
/**

* 点击确定

*/

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 都简单方便、统一。

代码:

?

1

2

3

4

5

6

7

8

9

10

11

12

13
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有所帮助,欢迎各位浏览本站其他专题并随时留言,小编会及时回复大家的。

原文链接:http://blog.csdn.net/u012643122/article/details/53032482

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

快网idc优惠网 建站教程 Java使用代理进行网络连接方法示例 https://www.kuaiidc.com/114376.html

相关文章

发表评论
暂无评论