mirror of
https://github.com/qaiu/netdisk-fast-download.git
synced 2025-12-16 12:23:03 +00:00
Merge branch 'main' of github.com:qaiu/netdisk-fast-download
This commit is contained in:
@@ -59,11 +59,20 @@ mvn -pl parser test
|
||||
本模块支持用户自定义解析器扩展。通过简单的配置和注册,你可以添加自己的网盘解析实现:
|
||||
|
||||
```java
|
||||
// 1. 实现 IPanTool 接口
|
||||
public class MyPanTool implements IPanTool {
|
||||
public MyPanTool(ShareLinkInfo info) { /* 必须提供此构造器 */ }
|
||||
// 1. 继承 PanBase 抽象类(推荐)
|
||||
public class MyPanTool extends PanBase {
|
||||
public MyPanTool(ShareLinkInfo info) {
|
||||
super(info);
|
||||
}
|
||||
@Override
|
||||
public Future<String> parse() { /* 实现解析逻辑 */ }
|
||||
public Future<String> parse() {
|
||||
// 使用 PanBase 提供的 HTTP 客户端
|
||||
client.getAbs("https://api.example.com")
|
||||
.send()
|
||||
.onSuccess(res -> complete(asJson(res).getString("url")))
|
||||
.onFailure(handleFail("请求失败"));
|
||||
return future();
|
||||
}
|
||||
}
|
||||
|
||||
// 2. 注册到系统
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
# 自定义解析器扩展指南
|
||||
|
||||
> 最后更新:2025-10-17
|
||||
|
||||
## 概述
|
||||
|
||||
本模块支持用户自定义解析器扩展。用户在依赖本项目的 Maven 坐标后,可以实现自己的网盘解析器并注册到系统中使用。
|
||||
@@ -27,49 +29,50 @@
|
||||
</dependency>
|
||||
```
|
||||
|
||||
### 步骤2: 实现 IPanTool 接口
|
||||
### 步骤2: 继承 PanBase 抽象类
|
||||
|
||||
创建自己的解析工具类,必须实现 `IPanTool` 接口:
|
||||
创建自己的解析工具类,**必须继承 `PanBase` 抽象类**(而不是直接实现 IPanTool 接口)。PanBase 提供了丰富的工具方法和 HTTP 客户端,简化解析器的开发。
|
||||
|
||||
```java
|
||||
package com.example.parser;
|
||||
|
||||
import cn.qaiu.entity.ShareLinkInfo;
|
||||
import cn.qaiu.parser.IPanTool;
|
||||
import cn.qaiu.parser.PanBase;
|
||||
import io.vertx.core.Future;
|
||||
import io.vertx.core.Promise;
|
||||
|
||||
/**
|
||||
* 自定义网盘解析器示例
|
||||
*/
|
||||
public class MyCustomPanTool implements IPanTool {
|
||||
|
||||
private final ShareLinkInfo shareLinkInfo;
|
||||
public class MyCustomPanTool extends PanBase {
|
||||
|
||||
/**
|
||||
* 必须提供 ShareLinkInfo 单参构造器
|
||||
*/
|
||||
public MyCustomPanTool(ShareLinkInfo shareLinkInfo) {
|
||||
this.shareLinkInfo = shareLinkInfo;
|
||||
super(shareLinkInfo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Future<String> parse() {
|
||||
Promise<String> promise = Promise.promise();
|
||||
|
||||
// 实现你的解析逻辑
|
||||
// 使用 PanBase 提供的 HTTP 客户端发起请求
|
||||
String shareKey = shareLinkInfo.getShareKey();
|
||||
String sharePassword = shareLinkInfo.getSharePassword();
|
||||
|
||||
try {
|
||||
// 调用你的网盘API,获取下载链接
|
||||
String downloadUrl = callYourPanApi(shareKey, sharePassword);
|
||||
promise.complete(downloadUrl);
|
||||
} catch (Exception e) {
|
||||
promise.fail(e);
|
||||
}
|
||||
// 示例:使用 client 发起 GET 请求
|
||||
client.getAbs("https://your-pan-domain.com/api/share/" + shareKey)
|
||||
.send()
|
||||
.onSuccess(res -> {
|
||||
// 使用 asJson 方法将响应转换为 JSON
|
||||
var json = asJson(res);
|
||||
String downloadUrl = json.getString("download_url");
|
||||
|
||||
// 使用 complete 方法完成 Promise
|
||||
complete(downloadUrl);
|
||||
})
|
||||
.onFailure(handleFail("请求下载链接失败"));
|
||||
|
||||
return promise.future();
|
||||
// 返回 Future
|
||||
return future();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -78,7 +81,7 @@ public class MyCustomPanTool implements IPanTool {
|
||||
@Override
|
||||
public Future<List<FileInfo>> parseFileList() {
|
||||
// 实现文件列表解析逻辑
|
||||
return IPanTool.super.parseFileList();
|
||||
return super.parseFileList();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -87,16 +90,96 @@ public class MyCustomPanTool implements IPanTool {
|
||||
@Override
|
||||
public Future<String> parseById() {
|
||||
// 实现根据ID解析的逻辑
|
||||
return IPanTool.super.parseById();
|
||||
}
|
||||
|
||||
private String callYourPanApi(String shareKey, String password) {
|
||||
// 实现你的网盘API调用逻辑
|
||||
return "https://your-pan-domain.com/download/" + shareKey;
|
||||
return super.parseById();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### PanBase 提供的核心方法
|
||||
|
||||
PanBase 为解析器开发提供了以下工具和方法:
|
||||
|
||||
#### HTTP 客户端
|
||||
- **`client`**: 标准 WebClient 实例,支持自动重定向
|
||||
- **`clientSession`**: 带会话管理的 WebClient,自动处理 Cookie
|
||||
- **`clientNoRedirects`**: 不自动重定向的 WebClient,用于需要手动处理重定向的场景
|
||||
|
||||
#### 响应处理
|
||||
- **`asJson(HttpResponse)`**: 将 HTTP 响应转换为 JsonObject,自动处理 gzip 压缩和异常
|
||||
- **`asText(HttpResponse)`**: 将 HTTP 响应转换为文本,自动处理 gzip 压缩
|
||||
|
||||
#### Promise 管理
|
||||
- **`complete(String)`**: 完成 Promise 并返回结果
|
||||
- **`future()`**: 获取 Promise 的 Future 对象
|
||||
- **`fail(String, Object...)`**: Promise 失败时记录错误信息
|
||||
- **`fail(Throwable, String, Object...)`**: Promise 失败时记录错误信息和异常
|
||||
- **`handleFail(String)`**: 生成失败处理器,用于请求的 onFailure 回调
|
||||
|
||||
#### 其他工具
|
||||
- **`nextParser()`**: 调用下一个解析器,用于通用域名解析转发
|
||||
- **`getDomainName()`**: 获取域名名称
|
||||
- **`shareLinkInfo`**: 分享链接信息对象,包含 shareKey、sharePassword 等
|
||||
- **`log`**: 日志记录器
|
||||
|
||||
### WebClient 请求流程
|
||||
|
||||
WebClient 是基于 Vert.x 的异步 HTTP 客户端,其请求流程如下:
|
||||
|
||||
1. **初始化 Vert.x 实例**
|
||||
```java
|
||||
Vertx vertx = Vertx.vertx();
|
||||
WebClientVertxInit.init(vertx);
|
||||
```
|
||||
|
||||
2. **创建解析器实例**
|
||||
- 继承 PanBase 的解析器会自动获得配置好的 WebClient 实例
|
||||
|
||||
3. **发起异步请求**
|
||||
```java
|
||||
client.getAbs("https://api.example.com/endpoint")
|
||||
.putHeader("User-Agent", "MyParser/1.0")
|
||||
.send()
|
||||
.onSuccess(res -> {
|
||||
// 处理成功响应
|
||||
JsonObject json = asJson(res);
|
||||
complete(json.getString("url"));
|
||||
})
|
||||
.onFailure(handleFail("请求失败"));
|
||||
```
|
||||
|
||||
4. **请求流程说明**
|
||||
- **GET 请求**: 使用 `client.getAbs(url).send()`
|
||||
- **POST 请求**: 使用 `client.postAbs(url).sendJson(body)` 或 `.sendForm(form)`
|
||||
- **会话请求**: 使用 `clientSession` 自动管理 Cookie
|
||||
- **禁用重定向**: 使用 `clientNoRedirects` 手动处理 302/301
|
||||
- **代理支持**: PanBase 构造器会自动处理 shareLinkInfo 中的代理配置
|
||||
|
||||
5. **响应处理**
|
||||
```java
|
||||
.onSuccess(res -> {
|
||||
// 检查状态码
|
||||
if (res.statusCode() != 200) {
|
||||
fail("请求失败,状态码:" + res.statusCode());
|
||||
return;
|
||||
}
|
||||
|
||||
// 解析 JSON 响应
|
||||
JsonObject json = asJson(res);
|
||||
|
||||
// 或解析文本响应
|
||||
String text = asText(res);
|
||||
|
||||
// 完成 Promise
|
||||
complete(result);
|
||||
})
|
||||
.onFailure(handleFail("网络请求异常"));
|
||||
```
|
||||
|
||||
6. **错误处理**
|
||||
- 使用 `fail()` 方法标记解析失败
|
||||
- 使用 `handleFail()` 生成统一的失败处理器
|
||||
- 所有异常会自动记录到日志
|
||||
|
||||
### 步骤3: 注册自定义解析器
|
||||
|
||||
在应用启动时注册你的解析器:
|
||||
@@ -173,10 +256,10 @@ public class Example {
|
||||
- 注册时会自动检查冲突
|
||||
|
||||
### 2. 构造器要求
|
||||
自定义解析器类必须提供 `ShareLinkInfo` 单参构造器:
|
||||
自定义解析器类必须提供 `ShareLinkInfo` 单参构造器,并调用父类构造器:
|
||||
```java
|
||||
public MyCustomPanTool(ShareLinkInfo shareLinkInfo) {
|
||||
this.shareLinkInfo = shareLinkInfo;
|
||||
super(shareLinkInfo);
|
||||
}
|
||||
```
|
||||
|
||||
@@ -230,8 +313,8 @@ import cn.qaiu.parser.CustomParserConfig;
|
||||
import cn.qaiu.parser.CustomParserRegistry;
|
||||
import cn.qaiu.parser.IPanTool;
|
||||
import cn.qaiu.parser.ParserCreate;
|
||||
import cn.qaiu.parser.PanBase;
|
||||
import io.vertx.core.Future;
|
||||
import io.vertx.core.Promise;
|
||||
|
||||
public class CompleteExample {
|
||||
|
||||
@@ -298,24 +381,31 @@ public class CompleteExample {
|
||||
}
|
||||
}
|
||||
|
||||
// 自定义解析器实现
|
||||
static class MyCustomPanTool implements IPanTool {
|
||||
private final ShareLinkInfo shareLinkInfo;
|
||||
// 自定义解析器实现(继承 PanBase)
|
||||
static class MyCustomPanTool extends PanBase {
|
||||
|
||||
public MyCustomPanTool(ShareLinkInfo shareLinkInfo) {
|
||||
this.shareLinkInfo = shareLinkInfo;
|
||||
super(shareLinkInfo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Future<String> parse() {
|
||||
Promise<String> promise = Promise.promise();
|
||||
|
||||
// 模拟解析逻辑
|
||||
// 使用 PanBase 提供的 HTTP 客户端
|
||||
String shareKey = shareLinkInfo.getShareKey();
|
||||
String downloadUrl = "https://mypan.com/download/" + shareKey;
|
||||
|
||||
promise.complete(downloadUrl);
|
||||
return promise.future();
|
||||
client.getAbs("https://mypan.com/api/share/" + shareKey)
|
||||
.send()
|
||||
.onSuccess(res -> {
|
||||
// 使用 asJson 解析响应
|
||||
var json = asJson(res);
|
||||
String downloadUrl = json.getString("download_url");
|
||||
|
||||
// 使用 complete 完成 Promise
|
||||
complete(downloadUrl);
|
||||
})
|
||||
.onFailure(handleFail("获取下载链接失败"));
|
||||
|
||||
return future();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user