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 代理竟能如此简单的更多相关文章
- linux配置wifi连接并通过ssh代理开启socks代理
1, 命令行配置连接wifi具体我是用的cubieboard2上Debian主机,其中配置wifi的命令行有wpa_cli,具体用法步骤如下.wpa_cli 命令行执行需要root权限,详细用法请见 ...
- JAVA知识积累 给HttpClient添加Socks代理
本文描述http client使用socks代理过程中需要注意的几个方面:1,socks5支持用户密码授权:2,支持https:3,支持让代理服务器解析DNS: 使用代理创建Socket 从原理上来看 ...
- 关于双网卡双宽带Http及Socks代理的配置
1.[硬件环境] a, 1台宿主(win7)+几十台虚拟机(xp)(vm10的版本,估计可打开52台以上的虚拟机) b, 双网卡,其中一个网卡通过路由连接电信ADSL,一个直连集线器,可直接连接移动m ...
- 给HttpClient添加Socks代理
本文描述http client使用socks代理过程中需要注意的几个方面:1,socks5支持用户密码授权:2,支持https:3,支持让代理服务器解析DNS: 使用代理创建Socket 从原理上来看 ...
- redsocks 将socks代理转换成全局代理
redsocks 需要手动下载编译.前置需求为libevent组件,当然gcc什么的肯定是必须的. 获取源码 git clone https://github.com/darkk/redsocks 安 ...
- Mac Aria2 使用Privoxy将socks代理转化为http代理
安装Privoxy 打开终端安装privoxy来实现这里我是通过brew来进行的安装 brew install privoxy 看到这行已经安装成功 ==> Caveats To have la ...
- 使用Java中的动态代理实现数据库连接池
2002 年 12 月 05 日 作者通过使用JAVA中的动态代理实现数据库连接池,使使用者可以以普通的jdbc连接的使用习惯来使用连接池. 数据库连接池在编写应用服务是经常需要用到的模块,太过频繁的 ...
- 使用ssh正向连接、反向连接、做socks代理的方法
ssh -L 219.143.16.157:58080:172.21.163.32:8080 用户名@localhost -p 10142 在 219.143.16.157机器执行 将ssh隧 ...
- springmvc java配置
配置DispatcherServlet DispatcherServlet的是SpringMVC的核心.在这里请求会第一次接触都框架,它要负责将请求路由到其他的组件之中. 使用Java配置将Dispa ...
- Xshell添加ssh隧道SOCKS代理
Xshell是一个功能强大的终端模拟器,支持SSH,SFTP.TELNET.RLOGIN和SERIAL 下载地址:http://www.netsarang.com/products/xsh_overv ...
随机推荐
- 非AI文生图,献丑了
多图预警! 大家好,我是 DOM哥 也许你会好奇上面的这几张图片是怎么生成的,接下来我就开始隆重介绍这款文生图工具 当然,并非 AI 的那个文生图啦 预览地址:https://dombro.site/ ...
- WPF入门教程系列二十四——DataGrid使用示例(2)
WPF入门教程系列目录 WPF入门教程系列二--Application介绍 WPF入门教程系列三--Application介绍(续) WPF入门教程系列四--Dispatcher介绍 WPF入门教程系 ...
- vernemq 一个可用的入门指南之一:Mac下的安装及使用,使用MQTTX访问verneMQ
因为百度到一篇简书的,不可用,所以写这么一篇,方便后来人 物联网的消息队列技术选型,很多地方会推荐使用VerneMQ,这里做一个安装实验记录,并非推荐. git clone https://githu ...
- 用rust 写一个jar包 class冲突检测工具
Rust很适合写命令行工具,特别是使用clap crate 更加方便,这篇文章介绍使用rust写一个jar包class冲突检测的工具.项目地址: https://github.com/Aitozi/j ...
- Singleton 单例模式简介与 C# 示例【创建型】【设计模式来了】
〇.简介 1.什么是单例模式? 一句话解释: 单一的类,只能自己来创建唯一的一个对象. 单例模式(Singleton Pattern)是日常开发中最简单的设计模式之一.这种类型的设计模式属于创建型 ...
- K2C V21.4.6.12刷breed教程
K2C V21.4.6.12刷breed教程(刷机方法源自qiao99) 原贴地址:K2C V21.4.6.12刷breed记录 http://www.right.com.cn/forum/threa ...
- Java(循环语句,数组)
Java循环 1.while while( 表达式 ) { //循环内容 } 2.do while do { //循环内容 }while(表达式); 3.for for(初始化; 表达式; 更新) { ...
- 聊一聊 Python 安装中的 --enable-shared
由于微信不允许外部链接,你需要点击文章尾部左下角的 "阅读原文",才能访问文中链接. 今天在 CentOS 7.4 使用源码编译安装 Python-2.7.15 的时候,发现了一个 ...
- 你是怎么学习 Java 技术的?
一.Java 语言 Java 语言不只是一门语言. Java 学习不是一蹴而就就可以达成的,它是一个循序渐进,由浅入深,由表及里的过程.尤其需要注意的是不能有浅尝辄耻,不求甚解的态度.每个地方只抓一点 ...
- 浅谈 thinkphp composer 扩展包加载原理
浅谈 thinkphp composer 扩展包加载原理 本文将介绍 ThinkPHP 中 Composer 扩展包的加载原理,帮助读者更好地理解和应用该功能. 前言 如题,今天感觉好久没有更新博客了 ...