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();

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
揭秘ChatGPT,如何打造自己的自定义指令 | 京东云技术团队
一、ChatGPT-0720更新 又在深夜,正要打开ChatGPT官网测试下pdf对话功能,发现ChatGPT又有更新。本次更新总结有2点: 1.对于Plus用户,GPT-4的使用限额从25条/3h提升至50条(整整提升1倍~ $20的订阅费又更超值了) 2.新增 Custom instructions (个性化指令),简单可以理解为个人角色和期望回答定义 Why instructions? Custom instructions中文翻译过来叫 个性化指令 会比较准确,为什么是instruction这个单词?在大语言模型的训练中,经常会看到 Instruct Tuning(指令微调)这个单词,GPT家族中也有一个 InstructGPT的模型(指令微调后的GPT),通过指令微调的LLM会更按照我们期望的方式输出。一些LLM的训练语料中也会采用instruction的形式: { "instruction": "将不同颜色混合后的结果", "input": "红色、黄色", "output": "橙色" } 对比指令和提示词,指令更像是引导指示命令的意思,提示词更像是可参考可...
- 下一篇
Java单元测试及常用语句 | 京东物流技术团队
1 前言 编写Java单元测试用例,即把一段复杂的代码拆解成一系列简单的单元测试用例,并且无需启动服务,在短时间内测试代码中的处理逻辑。写好Java单元测试用例,其实就是把“复杂问题简单化,建单问题深入化“。在编写的过程中, 我们也可以对自己的代码进行一个二次检查。 以下是我总结的一些编写单元测试的好处: 1.测试代码逻辑时,不需要启动整个应用。 2.单元测试可以覆盖边界值 3.提高原有代码的复用 4.可以有效避免代码改动后,对原有逻辑的潜在影响 2 准备环境 Mockito是目前最普遍的单元测试模拟框架。Mockito可以模拟应用中依赖的复杂对象,从而把测试对象和依赖对象隔离开。PowerMock为Mockito提供了扩展功能。为模拟静态方法,final类,和私有方法等。我们选择使用以Mockito为主,PowerMock为辅的框架来做单元测试。 2.1 引入Mockito和PowerMock包,在pom.xml文件中加入以下依赖: <properties> <powermock.version>2.0.9</powermock.version> ...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS7编译安装Gcc9.2.0,解决mysql等软件编译问题
- SpringBoot2整合Redis,开启缓存,提高访问速度
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- MySQL8.0.19开启GTID主从同步CentOS8
- Mario游戏-低调大师作品
- Linux系统CentOS6、CentOS7手动修改IP地址
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- Docker安装Oracle12C,快速搭建Oracle学习环境
- CentOS7安装Docker,走上虚拟化容器引擎之路