Java配置HTTP/Socks代理的简单快速上手方法
作者:公子骏
正文
在网络请求过程中,使用代理是一种常见的需求。代理服务器可以帮助我们隐藏真实的 IP 地址、加速访问速度、访问公司特定内网等等要求。在 Java 中,我们可以通过一些库或框架来实现代理的设置和使用。
但如果使用 OkHttp、HttpClient 亦或是 Retrofit 和 Feign,需要实现 Socks 协议代理都需要实现SSLSocketFactory
类或ConnectionSocketFactory
接口的子类,重写createSokcet
方法,实现起来非常的麻烦。如果代理还需要用户名密码验证(大部分都会有),还需要实现Authenticator
的子类,并通过ThreadLocal
分配到请求各自的线程中,整个过程需要自己写很多代码,无比烦人。
而本文将介绍如何使用一种最简单的方法,即使用声明式 HTTP 框架 Forest,结合@HTTPProxy
和 @SocksProxy
注解来发送 HTTP/HTTPS 请求,来快速实现代理功能。
Forest 的基本使用
添加 Forest 依赖
<dependency> <groupId>com.dtflys.forest</groupId> <artifactId>forest-spring-boot-starter</artifactId> <version>1.5.33</version> </dependency>
如果您的项目不是 spring-boot 项目,请看官方文档来配置不同环境下的依赖。
先看看没有代理的情况
// 定义一个 Forest 客户端接口 public interface MyClient { // 当调用该方法时,会自动使用 Get 请求访问地址 https://example.com @Get("https://example.com") String getData(); }
假如https://example.com
这个地址是需要通过代理才能正常访问,那么以下代码将不会成功
// 注入 Forest 客户端实例 @Resource MyClient myClient; ... ... // 网络请求将会失败 String data = myClient.getData();
使用 HTTP 代理
在接口上挂上@HTTPProxy
接口即可
// 通过 @HTTPProxy 注解配置代理服务的地址和端口 @HTTPProxy(host = "127.0.0.1", port = "1081") public interface MyClient { @Get("https://example.com") String getData(); }
如果代理服务需要验证
// 通过 @HTTPProxy 注解配置代理服务的地址和端口以及用户验证信息 @HTTPProxy(host = "127.0.0.1", port = "1081", username = "root", password = "123456") public interface MyClient { @Get("https://example.com") String getData(); }
使用 Socks 代理
如果您需要连的是 Socks 协议的代理端口,那也很简单,可以用上面的方法如法炮制,只不过注解名换了一下而已
// 通过 @SocksProxy 注解配置 Socks 协议代理服务的地址和端口 @SocksProxy(host = "127.0.0.1", port = "1081") public interface MyClient { @Get("https://example.com") String getData(); }
加上用户名密码
// 通过 @SocksProxy 注解配置 Socks 协议代理服务的地址和端口以及用户验证信息 @SocksProxy(host = "127.0.0.1", port = "1081", username = "root", password = "123456") public interface MyClient { @Get("https://example.com") String getData(); }
全局配置
如果不想把代理的参数(host, port 等)写死在注解代码中,可以通过字符串模板来引用配置文件的属性
先在application.yml
配置文件中添加以下配置(属性名可以自己随意起):
proxy: host: 127.0.0.1 port: 1081 username: root password: 123456
通过字符串模板在注解中进行引用
@SocksProxy( host = "#{proxy.host}", port = "#{proxy.port}", username = "#{proxy.username}", password = "#{proxy.password}" ) public interface MyClient { @Get("https://example.com") String getData(); }
封装注解
如果您有很多接口类要配置代理,并且不想在每个接口上放这么一大坨参数,可以使用自定义注解对@HTTPProxy
或@SocksProxy
进行封装
// 自定义一个注解 @MyProxy @Documented @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD, ElementType.TYPE}) // 将 @SockProxy 注解以及参数添加到这里 @SocksProxy( host = "#{proxy.host}", port = "#{proxy.port}", username = "#{proxy.username}", password = "#{proxy.password}" ) public @interface MyProxy { }
然后在需要代理的接口上挂上您自定义的@MyProxy
注解就可以了
@MyProxy public interface MyClient1 { @Get("https://example.com/data1") String getData1(); } @MyProxy public interface MyClient2 { @Get("https://example.com/data2") String getData2(); }
此时,MyClient1 和 MyClient2 接口的请求都会走同样的代理
非声明式方式
以上都是以声明式的方式,配合@HTTProxy
以及@SocksProxy
注解来完成 HTTP/Socks 代理的设置过程的。
如果不想定义接口、配置、注解等等玩意儿,那用编程式的API直接干就完了。
// 通过 HTTP 的代理发送请求 String data1 = Forest.get("https://example.com") .proxy(ForestProxy.http("127.0.0.1", 1081) .username("root") .password("123456")) .executeAsString(); // 通过 Socks 的代理发送请求 String data2 = Forest.get("https://example.com") .proxy(ForestProxy.socks("127.0.0.1", 1081) .username("root") .password("123456")) .executeAsString();
以上就是Java配置HTTP/Socks代理简单快速上手方法的详细内容,更多关于Java配置HTTP/Socks代理的资料请关注脚本之家其它相关文章!