1. 项目重命名

2. 添加UC网盘解析
3. 添加移动云空间解析 #1
This commit is contained in:
QAIU
2023-05-24 16:20:06 +08:00
parent 25534452ae
commit 00af483239
51 changed files with 526 additions and 349 deletions

View File

@@ -0,0 +1,33 @@
package cn.qaiu.lz;
import cn.qaiu.db.pool.JDBCPoolInit;
import cn.qaiu.vx.core.Deploy;
import cn.qaiu.vx.core.util.ConfigConstant;
import io.vertx.core.json.JsonObject;
/**
* 程序入口
* <br>Create date 2021-05-08 13:00:01
*
* @author qiu
*/
public class AppMain {
public static void main(String[] args) {
Deploy.instance().start(args, AppMain::exec);
}
/**
* 初始化数据库
*
* @param jsonObject 配置
*/
private static void exec(JsonObject jsonObject) {
if (jsonObject.getJsonObject(ConfigConstant.SERVER).getBoolean("enableDatabase")) {
JDBCPoolInit.builder().config(jsonObject.getJsonObject("dataSource")).build().initPool();
}
}
}

View File

@@ -0,0 +1,22 @@
package cn.qaiu.lz.common;
import io.vertx.core.json.JsonObject;
/**
* lz-web <br>
* 实现此接口 POJO转JSON对象
*
* @author <a href="https://qaiu.top">QAIU</a>
* <br>Create date 2021/8/27 11:40
*/
public interface ToJson {
/**
* POJO转JSON对象
*
* @return Json Object
*/
default JsonObject toJson() {
return JsonObject.mapFrom(this);
}
}

View File

@@ -0,0 +1,29 @@
package cn.qaiu.lz.common.interceptorImpl;
import cn.qaiu.vx.core.base.BaseHttpApi;
import cn.qaiu.vx.core.interceptor.Interceptor;
import cn.qaiu.vx.core.model.JsonResult;
import cn.qaiu.vx.core.util.CommonUtil;
import cn.qaiu.vx.core.util.SharedDataUtil;
import cn.qaiu.vx.core.util.VertxHolder;
import io.vertx.core.json.JsonArray;
import io.vertx.core.shareddata.LocalMap;
import io.vertx.ext.web.RoutingContext;
import lombok.extern.slf4j.Slf4j;
import lombok.val;
/**
* 默认拦截器实现
* 校验用户是否合法 <br>
* TODO 暂时只做简单实现
*/
@Slf4j
public class DefaultInterceptor implements Interceptor, BaseHttpApi {
private final JsonArray ignores = SharedDataUtil.getJsonArrayForCustomConfig("ignoresReg");
@Override
public void handle(RoutingContext ctx) {
ctx.next();
}
}

View File

@@ -0,0 +1,29 @@
package cn.qaiu.lz.common.model;
import io.vertx.codegen.annotations.DataObject;
import io.vertx.core.json.JsonObject;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
/**
*
* @author <a href="https://qaiu.top">QAIU</a>
* <br>Create date 2021/7/22 3:34
*/
@DataObject
@Data
@NoArgsConstructor
public class MyData implements Serializable {
public static final long serialVersionUID = 1L;
private String id;
private String maxSize;
public MyData(JsonObject jsonObject) {
// TODO
}
}

View File

@@ -0,0 +1,35 @@
package cn.qaiu.lz.common.model;
import cn.qaiu.lz.common.ToJson;
import io.vertx.codegen.annotations.DataObject;
import io.vertx.core.json.JsonObject;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* lz-web
*
* @author <a href="https://qaiu.top">QAIU</a>
* <br>Create date 2021/8/10 11:10
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@DataObject
public class UserInfo implements ToJson {
private String username;
private String permission;
private String pwdCrc32;
private String uuid;
public UserInfo(JsonObject jsonObject) {
this.username = jsonObject.getString("username");
this.permission = jsonObject.getString("permission");
this.pwdCrc32 = jsonObject.getString("pwdCrc32");
}
}

View File

@@ -0,0 +1,20 @@
package cn.qaiu.lz.common.util;
public class ArrayUtil {
public static int[] parseIntArray(String[] arr) {
int[] ints = new int[arr.length];
for (int i = 0; i < ints.length; i++) {
ints[i] = Integer.parseInt(arr[i]);
}
return ints;
}
public static float[] parseFloatArray(String[] arr) {
float[] ints = new float[arr.length];
for (int i = 0; i < ints.length; i++) {
ints[i] = Float.parseFloat(arr[i]);
}
return ints;
}
}

View File

@@ -0,0 +1,19 @@
package cn.qaiu.lz.common.util;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* 获取连接
*
* @author <a href="https://qaiu.top">QAIU</a>
*/
public enum ConnectUtil {
// 实现枚举单例
INSTANCE;
private static final Logger LOGGER = LoggerFactory.getLogger(ConnectUtil.class);
}

View File

@@ -0,0 +1,80 @@
package cn.qaiu.lz.common.util;
import cn.qaiu.vx.core.util.CastUtil;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.jsoup.Jsoup;
import java.util.Map;
/**
* 奶牛快传解析工具
*
* @author <a href="https://qaiu.top">QAIU</a>
* @date 2023/4/21 21:19
*/
@Slf4j
public class CowTool {
/*
First request:
{
"code": "0000",
"message": "success",
"data": {
"guid": "e4f41b51-b5da-4f60-9312-37aa10c0aad7",
"firstFile": {
"id": "23861191276513345",
}
}
}
Then request:
{
"code": "0000",
"message": "success",
"tn": "TN:DE0E092E8A464521983780FBA21D0CD3",
"data": {
"downloadUrl": "https://download.cowcs.com..."
}
}
*/
public static String parse(String fullUrl) throws Exception {
var uniqueUrl = fullUrl.substring(fullUrl.lastIndexOf('/') + 1);
var baseUrl = "https://cowtransfer.com/core/api/transfer/share";
var result = Jsoup
.connect(baseUrl + "?uniqueUrl=" + uniqueUrl).ignoreContentType(true)
.get()
.text();
var objectMapper = new ObjectMapper();
Map<String, Object> map = objectMapper.readValue(result, new TypeReference<>() {
});
if ("success".equals(map.get("message")) && map.containsKey("data")) {
Map<String, Object> data = CastUtil.cast(map.get("data"));
var guid = data.get("guid").toString();
Map<String, Object> firstFile = CastUtil.cast(data.get("firstFile"));
var fileId = firstFile.get("id").toString();
var result2 = Jsoup
.connect(baseUrl + "/download?transferGuid=" + guid + "&fileId=" + fileId)
.ignoreContentType(true)
.get()
.text();
Map<String, Object> map2 = objectMapper.readValue(result2, new TypeReference<>() {});
if ("success".equals(map2.get("message")) && map2.containsKey("data")) {
Map<String, Object> data2 = CastUtil.cast(map2.get("data"));
var downloadUrl = data2.get("downloadUrl").toString();
if (StringUtils.isNotEmpty(downloadUrl)) {
log.info("cow parse success: {}", downloadUrl);
return downloadUrl;
}
}
}
log.info("Cow parse field------------->end");
throw new Exception("Cow解析失败");
}
}

View File

@@ -0,0 +1,65 @@
package cn.qaiu.lz.common.util;
import cn.qaiu.vx.core.util.VertxHolder;
import io.vertx.core.Future;
import io.vertx.core.Promise;
import io.vertx.core.json.JsonArray;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.web.client.WebClient;
import io.vertx.uritemplate.UriTemplate;
import lombok.extern.slf4j.Slf4j;
/**
* 移动云空间解析
*/
@Slf4j
public class EcTool {
private static final String FULL_URL_PREFIX = "https://www.ecpan.cn/drive/fileextoverrid" +
".do?chainUrlTemplate=https:%2F%2Fwww.ecpan" +
".cn%2Fweb%2F%23%2FyunpanProxy%3Fpath%3D%252F%2523%252Fdrive%252Foutside&parentId=-1&data={dataKey}";
private static final String DOWNLOAD_REQUEST_URL = "https://www.ecpan.cn/drive/sharedownload.do";
public static final String EC_HOST = "www.ecpan.cn";
public static Future<String> parse(String dataKey) {
Promise<String> promise = Promise.promise();
WebClient client = WebClient.create(VertxHolder.getVertxInstance());
// 第一次请求 获取文件信息
client.getAbs(UriTemplate.of(FULL_URL_PREFIX)).setTemplateParam("dataKey", dataKey).send().onSuccess(res -> {
JsonObject jsonObject = res.bodyAsJsonObject();
log.debug("ecPan get file info -> {}", jsonObject);
JsonObject fileInfo = jsonObject
.getJsonObject("var")
.getJsonObject("chainFileInfo");
if (!fileInfo.containsKey("errMesg")) {
JsonObject cloudpFile = fileInfo.getJsonObject("cloudpFile");
JsonArray fileIdList = JsonArray.of(cloudpFile);
// 构造请求JSON {"extCodeFlag":0,"isIp":0}
JsonObject requestBodyJson = JsonObject.of("extCodeFlag", 0, "isIp", 0);
requestBodyJson.put("shareId", Integer.parseInt(fileInfo.getString("shareId"))); // 注意shareId
// 数据类型
requestBodyJson.put("groupId", cloudpFile.getString("groupId"));
requestBodyJson.put("fileIdList", fileInfo.getJsonArray("cloudpFileList"));
// 第二次请求 获取下载链接
client.postAbs(DOWNLOAD_REQUEST_URL)
.sendJsonObject(requestBodyJson).onSuccess(res2 -> {
JsonObject jsonRes = res2.bodyAsJsonObject();
log.debug("ecPan get download url -> {}", res2.body().toString());
promise.complete(jsonRes.getJsonObject("var").getString("downloadUrl"));
}).onFailure(t -> {
promise.fail(new RuntimeException("解析异常: key = " + dataKey, t.fillInStackTrace()));
});
} else {
promise.fail(new RuntimeException(DOWNLOAD_REQUEST_URL + " 解析失败: "
+ fileInfo.getString("errMesg")) + " key = " + dataKey);
}
}
).onFailure(t -> {
promise.fail(new RuntimeException("解析异常: key = " + dataKey, t.fillInStackTrace()));
});
return promise.future();
}
}

View File

@@ -0,0 +1,95 @@
package cn.qaiu.lz.common.util;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.jsoup.Jsoup;
import java.io.IOException;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* 蓝奏云解析工具
*
* @author QAIU
* @version 1.0 update 2021/5/16 10:39
*/
public class LzTool {
public static String parse(String fullUrl) throws Exception {
var userAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.3";
var url = fullUrl.substring(0, fullUrl.lastIndexOf('/') + 1);
var id = fullUrl.substring(fullUrl.lastIndexOf('/') + 1);
Map<String, String> header = new HashMap<>();
header.put("Accept-Language", "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2");
header.put("referer", url);
/*
// 部分链接需要设置安卓UA
sec-ch-ua: "Google Chrome";v="111", "Not(A:Brand";v="8", "Chromium";v="111"
sec-ch-ua-mobile: ?1
sec-ch-ua-platform: "Android"
*/
var userAgent2 = "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36";
Map<String, String> header2 = new HashMap<>();
header2.put("Accept-Language", "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2");
header2.put("sec-ch-ua-mobile", "sec-ch-ua-mobile");
header2.put("sec-ch-ua-platform", "Android");
header2.put("referer", url);
//第一次请求获取iframe的地址
String result = Jsoup.connect(url + id)
.userAgent(userAgent)
.get()
.select(".ifr2")
.attr("src");
//第二次请求得到js里的json数据里的sign
result = Jsoup.connect(url + result)
.headers(header)
.userAgent(userAgent)
.get()
.html();
// System.out.println(result);
// 'sign':'AWcGOFprUGFWX1BvBTVXawdrBDZTOAU_bV2FTZFU7W2sBJ1t4DW0FYFIyBmgDZVJgUjAFNV41UGQFNg_c_c' 改下正则TMD 最近上传竟然没_c_c
Matcher matcher = Pattern.compile("'sign'\s*:\s*'([0-9a-zA-Z_]+)'").matcher(result);
Map<String, String> params = new LinkedHashMap<>();
if (matcher.find()) {
String sn = matcher.group(1).replace("'", "");
params.put("action", "downprocess");
params.put("sign", sn);
params.put("ves", "1");
// System.out.println(sn);
} else {
throw new IOException();
}
//第三次请求 通过参数发起post请求,返回json数据
result = Jsoup
.connect(url + "ajaxm.php")
.headers(header)
.userAgent(userAgent)
.data(params)
.post()
.text()
.replace("\\", "");
//json转为map
params = new ObjectMapper().readValue(result, new TypeReference<>() {});
// System.out.println(params);
//通过json的数据拼接出最终的URL发起第最终请求,并得到响应信息头
url = params.get("dom") + "/file/" + params.get("url");
var headers = Jsoup.connect(url)
.ignoreContentType(true)
.userAgent(userAgent2)
.headers(header2)
.followRedirects(false)
.execute()
.headers();
//得到重定向的地址进行重定向
url = headers.get("Location");
return url;
}
}

View File

@@ -0,0 +1,87 @@
package cn.qaiu.lz.common.util;
import cn.qaiu.vx.core.util.VertxHolder;
import io.vertx.core.Future;
import io.vertx.core.Promise;
import io.vertx.core.json.JsonArray;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.web.client.WebClient;
import io.vertx.uritemplate.UriTemplate;
import lombok.extern.slf4j.Slf4j;
/**
* 移动云空间解析
*/
@Slf4j
public class UcTool {
private static final String API_URL_PREFIX = "https://pc-api.uc.cn/1/clouddrive/";
public static final String FULL_URL_PREFIX = "https://fast.uc.cn/s/";
private static final String FIRST_REQUEST_URL = API_URL_PREFIX + "share/sharepage/token?entry=ft&fr=pc&pr" +
"=UCBrowser";
private static final String SECOND_REQUEST_URL = API_URL_PREFIX + "transfer_share/detail?pwd_id={pwd_id}&passcode" +
"={passcode}&stoken={stoken}";
private static final String THIRD_REQUEST_URL = API_URL_PREFIX + "file/download?entry=ft&fr=pc&pr=UCBrowser";
public static Future<String> parse(String data, String code) {
if (!data.startsWith(FULL_URL_PREFIX)) {
data = FULL_URL_PREFIX + data;
}
var passcode = (code == null) ? "" : code;
var dataKey = data.substring(FULL_URL_PREFIX.length());
Promise<String> promise = Promise.promise();
var client = WebClient.create(VertxHolder.getVertxInstance());
var jsonObject = JsonObject.of("share_for_transfer", true);
jsonObject.put("pwd_id", dataKey);
jsonObject.put("passcode", passcode);
// 第一次请求 获取文件信息
client.postAbs(FIRST_REQUEST_URL).sendJsonObject(jsonObject).onSuccess(res -> {
log.debug("第一阶段 {}", res.body());
var resJson = res.bodyAsJsonObject();
if (resJson.getInteger("code") != 0) {
promise.fail(FIRST_REQUEST_URL + " 返回异常: " + resJson);
return;
}
var stoken = resJson.getJsonObject("data").getString("stoken");
// 第二次请求
client.getAbs(UriTemplate.of(SECOND_REQUEST_URL))
.setTemplateParam("pwd_id", dataKey)
.setTemplateParam("passcode", passcode)
.setTemplateParam("stoken", stoken)
.send().onSuccess(res2 -> {
log.debug("第二阶段 {}", res2.body());
JsonObject resJson2 = res2.bodyAsJsonObject();
if (resJson2.getInteger("code") != 0) {
promise.fail(FIRST_REQUEST_URL + " 返回异常: " + resJson2);
return;
}
// 文件信息
var info = resJson2.getJsonObject("data").getJsonArray("list").getJsonObject(0);
// 第二次请求
var bodyJson = JsonObject.of()
.put("fids", JsonArray.of(info.getString("fid")))
.put("pwd_id", dataKey)
.put("stoken", stoken)
.put("fids_token", JsonArray.of(info.getString("share_fid_token")));
client.postAbs(THIRD_REQUEST_URL).sendJsonObject(bodyJson)
.onSuccess(res3 -> {
log.debug("第三阶段 {}", res3.body());
var resJson3 = res3.bodyAsJsonObject();
if (resJson3.getInteger("code") != 0) {
promise.fail(FIRST_REQUEST_URL + " 返回异常: " + resJson2);
return;
}
promise.complete(resJson3.getJsonArray("data").getJsonObject(0).getString("download_url"));
})
.onFailure(t -> promise
.fail(new RuntimeException("解析异常: ", t.fillInStackTrace())));
}).onFailure(t -> promise.fail(new RuntimeException("解析异常: ", t.fillInStackTrace())));
}
).onFailure(t -> promise.fail(new RuntimeException("解析异常: key = " + dataKey, t.fillInStackTrace())));
return promise.future();
}
}

View File

@@ -0,0 +1,10 @@
/**
* lz-web
* <br>Create date 2021/7/8 13:29
*
* @author <a href="https://qaiu.top">QAIU</a>
*/
@ModuleGen(name = "proxy", groupPackage = "cn.qaiu.lz", useFutures = true)
package cn.qaiu.lz;
import io.vertx.codegen.annotations.ModuleGen;

View File

@@ -0,0 +1,158 @@
package cn.qaiu.lz.web.http;
import cn.qaiu.lz.common.util.CowTool;
import cn.qaiu.lz.common.util.EcTool;
import cn.qaiu.lz.common.util.LzTool;
import cn.qaiu.lz.common.util.UcTool;
import cn.qaiu.lz.web.model.SysUser;
import cn.qaiu.lz.web.service.UserService;
import cn.qaiu.vx.core.annotaions.RouteHandler;
import cn.qaiu.vx.core.annotaions.RouteMapping;
import cn.qaiu.vx.core.enums.RouteMethod;
import cn.qaiu.vx.core.model.JsonResult;
import cn.qaiu.vx.core.util.AsyncServiceUtil;
import io.vertx.core.Future;
import io.vertx.core.Promise;
import io.vertx.core.http.HttpServerRequest;
import io.vertx.core.http.HttpServerResponse;
import lombok.extern.slf4j.Slf4j;
import static io.vertx.core.http.HttpHeaders.CONTENT_TYPE;
/**
* 服务API
* <br>Create date 2021/4/28 9:15
*
* @author <a href="https://qaiu.top">QAIU</a>
*/
@Slf4j
@RouteHandler("/")
public class ServerApi {
private final UserService userService = AsyncServiceUtil.getAsyncServiceInstance(UserService.class);
@RouteMapping(value = "/login", method = RouteMethod.POST)
public Future<String> login(SysUser user) {
log.info("<------- login: {}", user.getUsername());
return userService.login(user);
}
@RouteMapping(value = "/test2", method = RouteMethod.GET)
public JsonResult<String> test01() {
return JsonResult.data("ok");
}
@RouteMapping(value = "/parser", method = RouteMethod.GET)
public Future<Void> parse(HttpServerResponse response, HttpServerRequest request, String url, String pwd) {
Promise<Void> promise = Promise.promise();
if (url.contains("lanzou")) {
String urlDownload = null;
try {
urlDownload = LzTool.parse(url);
log.info("url = {}", urlDownload);
response.putHeader("location", urlDownload).setStatusCode(302).end();
promise.complete();
} catch (Exception e) {
promise.fail(e);
}
} else if (url.contains("cowtransfer.com")) {
String urlDownload = null;
try {
urlDownload = CowTool.parse(url);
response.putHeader("location", urlDownload).setStatusCode(302).end();
promise.complete();
} catch (Exception e) {
promise.fail(e);
}
} else if (url.contains(EcTool.EC_HOST)) {
// 默认读取Url参数会被截断手动获取一下其他参数
String data = request.getParam("data");
EcTool.parse(data).onSuccess(resUrl -> {
response.putHeader("location", resUrl).setStatusCode(302).end();
promise.complete();
}).onFailure(t -> {
promise.fail(t.fillInStackTrace());
});
} else if (url.contains(UcTool.FULL_URL_PREFIX)) {
UcTool.parse(url, pwd).onSuccess(resUrl -> {
response.putHeader("location", resUrl).setStatusCode(302).end();
promise.complete();
}).onFailure(t -> {
promise.fail(t.fillInStackTrace());
});
}
return promise.future();
}
@RouteMapping(value = "/lz/:id", method = RouteMethod.GET)
public void lzParse(HttpServerResponse response, String id) throws Exception {
var url = "https://wwsd.lanzoue.com/" + id;
var urlDownload = LzTool.parse(url);
log.info("url = {}", urlDownload);
response.putHeader("location", urlDownload).setStatusCode(302).end();
}
@RouteMapping(value = "/cow/:id", method = RouteMethod.GET)
public void cowParse(HttpServerResponse response, String id) throws Exception {
var url = "https://cowtransfer.com/s/" + id;
var urlDownload = CowTool.parse(url);
response.putHeader("location", urlDownload).setStatusCode(302).end();
}
@RouteMapping(value = "/json/lz/:id", method = RouteMethod.GET)
public JsonResult<String> lzParseJson(HttpServerResponse response, String id) throws Exception {
var url = "https://wwsd.lanzoue.com/" + id;
var urlDownload = LzTool.parse(url);
log.info("url = {}", urlDownload);
return JsonResult.data(urlDownload);
}
@RouteMapping(value = "/json/cow/:id", method = RouteMethod.GET)
public JsonResult<String> cowParseJson(HttpServerResponse response, String id) throws Exception {
var url = "https://cowtransfer.com/s/" + id;
return JsonResult.data(CowTool.parse(url));
}
@RouteMapping(value = "/ec/:id", method = RouteMethod.GET)
public void ecParse(HttpServerResponse response, String id) {
EcTool.parse(id).onSuccess(resUrl -> {
response.putHeader("location", resUrl).setStatusCode(302).end();
}).onFailure(t -> {
response.putHeader(CONTENT_TYPE, "text/html;charset=utf-8");
response.end(t.getMessage());
});
}
@RouteMapping(value = "/json/ec/:id", method = RouteMethod.GET)
public Future<String> ecParseJson(HttpServerResponse response, String id) {
return EcTool.parse(id);
}
@RouteMapping(value = "/uc/:id", method = RouteMethod.GET)
public void ucParse(HttpServerResponse response, String id) {
String code = "";
if (id.contains("#")) {
String[] ids = id.split("#");
id = ids[0];
code = ids[1];
}
UcTool.parse(id, code).onSuccess(resUrl -> {
response.putHeader("location", resUrl).setStatusCode(302).end();
}).onFailure(t -> {
response.putHeader(CONTENT_TYPE, "text/html;charset=utf-8");
response.end(t.getMessage());
});
}
@RouteMapping(value = "/json/uc/:id", method = RouteMethod.GET)
public Future<String> ucParseJson(String id) {
String code = "";
if (id.contains("#")) {
String[] ids = id.split("#");
id = ids[0];
code = ids[1];
}
return UcTool.parse(id, code);
}
}

View File

@@ -0,0 +1,4 @@
package cn.qaiu.lz.web.model;
public class CowUser {
}

View File

@@ -0,0 +1,4 @@
package cn.qaiu.lz.web.model;
public class LzUser {
}

View File

@@ -0,0 +1,26 @@
package cn.qaiu.lz.web.model;
import cn.qaiu.db.ddl.Table;
import cn.qaiu.lz.common.ToJson;
import io.vertx.codegen.annotations.DataObject;
import io.vertx.core.json.JsonObject;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
@DataObject
@Table("t_user")
public class SysUser implements ToJson {
private String id;
private String username;
private String password;
public SysUser(JsonObject json) {
this.username = json.getString("username");
this.password = json.getString("password");
}
}

View File

@@ -0,0 +1,19 @@
package cn.qaiu.lz.web.service;
import cn.qaiu.lz.common.model.UserInfo;
import cn.qaiu.vx.core.base.BaseAsyncService;
import io.vertx.codegen.annotations.ProxyGen;
import io.vertx.core.Future;
import io.vertx.core.json.JsonObject;
/**
* lz-web
* <br>Create date 2021/7/12 17:16
*
* @author <a href="https://qaiu.top">QAIU</a>
*/
@ProxyGen
public interface DbService extends BaseAsyncService {
Future<JsonObject> sayOk(String data);
Future<JsonObject> sayOk2(String data, UserInfo holder);
}

View File

@@ -0,0 +1,18 @@
package cn.qaiu.lz.web.service;
import cn.qaiu.vx.core.util.CastUtil;
import java.lang.reflect.Proxy;
/**
* JDK代理类工厂
*/
public class JdkProxyFactory {
public static <T> T getProxy(T target) {
return CastUtil.cast(Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
new ServiceJdkProxy<>(target))
);
}
}

View File

@@ -0,0 +1,29 @@
package cn.qaiu.lz.web.service;
import lombok.extern.slf4j.Slf4j;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* lz-web
* <br>Create date 2021/8/25 14:28
*
* @author <a href="https://qaiu.top">QAIU</a>
*/
@Slf4j
public class ServiceJdkProxy<T> implements InvocationHandler {
private final T target;
public ServiceJdkProxy(T target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws InvocationTargetException, IllegalAccessException {
return method.invoke(target, args);
}
}

View File

@@ -0,0 +1,17 @@
package cn.qaiu.lz.web.service;
import cn.qaiu.lz.web.model.SysUser;
import cn.qaiu.vx.core.base.BaseAsyncService;
import io.vertx.codegen.annotations.ProxyGen;
import io.vertx.core.Future;
/**
* lz-web
* <br>Create date 2021/8/27 14:06
*
* @author <a href="https://qaiu.top">QAIU</a>
*/
@ProxyGen
public interface UserService extends BaseAsyncService {
Future<String> login(SysUser user);
}

View File

@@ -0,0 +1,38 @@
package cn.qaiu.lz.web.service.impl;
import cn.qaiu.lz.common.model.UserInfo;
import cn.qaiu.lz.web.service.DbService;
import cn.qaiu.vx.core.annotaions.Service;
import cn.qaiu.vx.core.model.JsonResult;
import io.vertx.core.Future;
import io.vertx.core.json.JsonObject;
import lombok.extern.slf4j.Slf4j;
/**
* lz-web
* <br>Create date 2021/7/12 17:26
*
* @author <a href="https://qaiu.top">QAIU</a>
*/
@Slf4j
@Service
public class DbServiceImpl implements DbService {
@Override
public Future<JsonObject> sayOk(String data) {
log.info("say ok1 -> wait...");
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return Future.succeededFuture(JsonObject.mapFrom(JsonResult.data("Hi: " + data)));
}
@Override
public Future<JsonObject> sayOk2(String data, UserInfo holder) {
// val context = VertxHolder.getVertxInstance().getOrCreateContext();
// log.info("say ok2 -> " + context.get("username"));
// log.info("--> {}", holder.toString());
return Future.succeededFuture(JsonObject.mapFrom(JsonResult.data("Hi: " + data)));
}
}

View File

@@ -0,0 +1,22 @@
package cn.qaiu.lz.web.service.impl;
import cn.qaiu.lz.web.model.SysUser;
import cn.qaiu.lz.web.service.UserService;
import cn.qaiu.vx.core.annotaions.Service;
import io.vertx.core.Future;
/**
* lz-web
* <br>Create date 2021/8/27 14:09
*
* @author <a href="https://qaiu.top">QAIU</a>
*/
@Service
public class UserServiceImpl implements UserService {
@Override
public Future<String> login(SysUser user) {
return Future.succeededFuture("111");
}
}

View File

@@ -0,0 +1,41 @@
# 服务配置
server:
port: 6400
contextPath: /
# 使用静态页面
enableStaticHtmlService: false
# 使用数据库
enableDatabase: false
staticResourcePath: webroot/
# 反向代理服务器配置路径(不用加后缀)
proxyConf: server-proxy
vertx:
eventLoopPoolSize: 8
workerPoolSize: 20
custom:
asyncServiceInstances: 8
routerLocations: cn.qaiu.lz.web.http
interceptorClassPath: cn.qaiu.lz.common.interceptorImpl.DefaultInterceptor
handlerLocations: cn.qaiu.lz.web.service
ignoresReg:
- .*/login$
- .*/test.*$
entityPackagesReg:
- ^cn\.qaiu\.lz\.web\.model\..*
errorPage404: /index.html
indexPage: /test2
sharedLogin: true
lzConfig:
config: '111'
dataSource:
provider_class: io.vertx.ext.jdbc.spi.impl.HikariCPDataSourceProvider
jdbcUrl: jdbc:h2:tcp://127.0.0.1:9095/./db/myData;MODE=MySQL;DATABASE_TO_LOWER=FALSE
driverClassName: org.h2.Driver
username: root
password: '123456'
tableClassPath: cn.qaiu.lz.web.model
cowConfig:
config: '111'

View File

@@ -0,0 +1,7 @@
# 要激活的配置: dev--连接本地数据库; prod连接线上数据库
active: dev
# 框架版本号 和主版本号
version_vertx: 4.1.3
version_app: 0.0.1
# 公司名称 -> LOGO版权文字
copyright: QAIU

View File

@@ -0,0 +1,3 @@
{
}

View File

@@ -0,0 +1,3 @@
curl -F "file=@C:\Users\qaiu\Desktop\real\lz-web\web\src\main\resources\logback.xml" -i -XPOST 127.0.0.1:8088/demo/basePointApi/importTags
curl -F "file=@C:\Users\qaiu\Desktop\3.csv" -i -XPOST 127.0.0.1:8088/demo/basePointApi/importTags

View File

@@ -0,0 +1,88 @@
### https://www.ecpan.cn/web/#/yunpanProxy?path=%2F%23%2Fdrive%2Foutside&data=81027a5c99af5b11ca004966c945cce6W9Bf2&isShare=1
### ecpan(移动云空间)
https://www.ecpan.cn/drive/fileextoverrid.do?chainUrlTemplate=https:%2F%2Fwww.ecpan.cn%2Fweb%2F%23%2FyunpanProxy%3Fpath%3D%252F%2523%252Fdrive%252Foutside&data=81027a5c99af5b11ca004966c945cce6W9Bf2&parentId=-1
###
POST https://www.ecpan.cn/drive/sharedownload.do
Content-Type: application/json
{
"extCodeFlag": 0,
"isIp": 0,
"shareId": 2404783,
"groupId": "c27b53c4f91b11ed86b3b026287b20b1",
"fileIdList": [{
"tableName": "cloudp_file_52",
"appFileId": "2d06ad61f91c11ed86b3b026287b20b1",
"dfsFileId": "3080817de83747698ff5747e25f97e50",
"fileName": "fonts.zip",
"filePath": "个人盘",
"fileLevel": 0,
"fileCount": 0,
"fileType": 2,
"fileSort": 99,
"fileSize": 19115063,
"uploadSize": 19115063,
"parentId": "c27b53c4f91b11ed86b3b026287b20b1",
"usn": 11364252,
"userName": "157****1073",
"userId": "",
"corpId": 13260232,
"createDate": 1684813492000,
"modifyDate": 1684813492000,
"status": 1,
"version": 0,
"comeFrom": 21,
"isShare": 0,
"folderType": 0,
"groupDesc": null,
"groupId": "c27b53c4f91b11ed86b3b026287b20b1",
"groupName": null,
"permission": null,
"userInfo": null,
"diskType": 1,
"historyKey": null,
"oldAppFileId": null,
"fileRealPath": null,
"fileExt": null,
"oldFileName": null,
"key": null,
"isUpperCase": null,
"isSubDir": null,
"isViewFolder": null,
"uploadTimeType": null,
"startUploadTime": null,
"endUploadTime": null,
"sizeOperator": null,
"orderField": null,
"orderBy": null,
"oldFilePath": null,
"statusStr": null,
"rootUsn": 11364252,
"createdByUsn": null,
"attentionCount": 0,
"fileMd5": "86c1ff32437ca0ccaca24f7ea197e34a",
"fileLabel": null,
"fileDesc": null,
"fileExtends": "<fileExtends><shareRoot></shareRoot><isLock>0</isLock><isEncrypt>0</isEncrypt></fileExtends>",
"deviceId": null,
"fileNamePinyin": "fonts.zip",
"modifyUser": "157****1073",
"fileExFileds": {
"shareRoot": "",
"isLock": 0,
"isEncrypt": 0
},
"security": 0,
"createdDate": null,
"modifiedDate1": null,
"modifiedDate2": null,
"createdDate1": null,
"createdDate2": null,
"deleteUsn": null,
"toShares": null,
"firstLevel": null
}]
}

View File

@@ -0,0 +1,158 @@
###
GET http://127.0.0.1:6400/api/serverApi/test3?fullUrl=https://wwp.lanzoux.com/iNvid035jgcb
###
# @no-redirect
GET http://127.0.0.1:6400/parser?url=https://lanzoux.com/ia2cntg
###
# @no-redirect
GET http://127.0.0.1:6400/parser?url=https://cowtransfer.com/s/9a644fe3e3a748
###
# @no-redirect
GET http://127.0.0.1:6400/cow/9a644fe3e3a748
###
# @no-redirect
GET http://127.0.0.1:6400/lz/ia2cntg
###
GET http://127.0.0.1:6400/json/lz/ia2cntg
###
GET http://127.0.0.1:6400/json/cow/9a644fe3e3a748
###
//https://cowtransfer.com/s/9a644fe3e3a748
https://cowtransfer.com/core/api/transfer/share?uniqueUrl=9a644fe3e3a748
###
https://cowtransfer.com/core/api/transfer/share?uniqueUrl=e4f41b51b5da4f
###
https://cowtransfer.com/core/api/transfer/share/download?transferGuid=e4f41b51-b5da-4f60-9312-37aa10c0aad7&fileId=23861191276513345
//https://download.cowcs.com/cowtransfer/cowtransfer/29188/db32e132e69f490eb4a343b398990f4b.docx?auth_key=1682111861-7b9579fbebb84aaba6bca368d083ab12-0-cbf009f3ffbcbb86191b8cdbc103abce&biz_type=1&business_code=COW_TRANSFER&channel_code=COW_CN_WEB&response-content-disposition=attachment%3B%20filename%3D05-CGB-DB-MENU-V1.02.docx%3Bfilename*%3Dutf-8%27%2705-CGB-DB-MENU-V1.02.docx&user_id=1023860921943729188&x-verify=1
#V2 api
###
https://cowtransfer.com/core/api/dam/asset/files/download/23890683765739569/url/v2
authorization: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJndWlkIjoiMDc1OTMwNGItMDEwZS00MGJiLTlhNDUtZTczY2Q5ODYzMDQwIiwiZXhwIjoxNjgzNzkzOTExfQ.rE9z0vhogPjUC0I92MqU8U_PKe4j_mGn7lGgPFMGt5c
###
POST https://cowtransfer.com/api/user/emaillogin
Content-Type: multipart/form-data; boundary=WebAppBoundary
--WebAppBoundary
Content-Disposition: form-data; name="email"
736226400@qq.com
--WebAppBoundary
Content-Disposition: form-data; name="password"
4458225ff
--WebAppBoundary--
# eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJndWlkIjoiMDc1OTMwNGItMDEwZS00MGJiLTlhNDUtZTczY2Q5ODYzMDQwIiwiZXhwIjoxNjg0NDYyMjMzfQ.AeuB5-aQUlgudoLDRgvFodlHx2qKiPFx3BAqGA0R-eE
# eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJndWlkIjoiMDc1OTMwNGItMDEwZS00MGJiLTlhNDUtZTczY2Q5ODYzMDQwIiwiZXhwIjoxNjg0NDYyMjMzfQ.AeuB5-aQUlgudoLDRgvFodlHx2qKiPFx3BAqGA0R-eE
###
POST https://cowtransfer.com/api/user/register/emailregistrationcheck
Content-Type: multipart/form-data; boundary=WebAppBoundary
--WebAppBoundary
Content-Disposition: form-data; name="email"
736226400@qq.com
--WebAppBoundary
Content-Disposition: form-data; name="joinProToken"
--WebAppBoundary--
### Send a form with the text and file fields
POST https://httpbin.org/post
Content-Type: multipart/form-data; boundary=WebAppBoundary
--WebAppBoundary
Content-Disposition: form-data; name="element-name"
Content-Type: text/plain
Name
--WebAppBoundary
Content-Disposition: form-data; name="data"; filename="data.json"
Content-Type: application/json
< ./request-form-data.json
--WebAppBoundary--
###
POST https://drive-pc.quark.cn/1/clouddrive/file/download?pr=ucpro&fr=pc
content-type: application/json;charset=UTF-8
cookie: __pus=77641f2139b914c29ed2b0caf246723dAAQbjDyR/fi1Z9YqqWbfO2qPZYeRTrFSC2P30uuWJwtY2ZwwQTRsEPHJKc9nuPnrXfQxir+0N8K/mVfr7SIwGc2t;
{"fids":["b3faf7f72ac64f94b4749588fc197816"]}
###
POST https://drive.quark.cn/1/clouddrive/file/download?pr=ucpro&fr=pc&ve=2.1.5
content-type: application/json;charset=UTF-8
cookie: __pus=77641f2139b914c29ed2b0caf246723dAAQbjDyR/fi1Z9YqqWbfO2qPZYeRTrFSC2P30uuWJwtY2ZwwQTRsEPHJKc9nuPnrXfQxir+0N8K/mVfr7SIwGc2t;
user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) quark-cloud-drive/2.5.20 Chrome/100.0.4896.160 Electron/18.3.5.4-b478491100 Safari/537.36 Channel/pckk_other_ch
{"fids":["b3faf7f72ac64f94b4749588fc197816"]}
###
https://dl-pc-zb-cf.pds.quark.cn/KTb1G4Lr/623810984/645b44ef8d9c47afbd2f4947b4b89d098f725188/645b44ef1eb3ebc1a8b448eb992b0e9195dfb646?Expires=1684137387&OSSAccessKeyId=LTAIyYfxTqY7YZsg&Signature=M5X1La7lpOJLRGZioFIMHRujuPs%3D&x-oss-traffic-limit=503316480&response-content-disposition=attachment%3B%20filename%3DC%23%20Shell%20%28C%23%20Offline%20Compiler%29_2.5.16.apk&u5=489aa5c778a51f717585a253ce8290a1&callback=eyJjYWxsYmFja0JvZHlUeXBlIjoiYXBwbGljYXRpb24vanNvbiIsImNhbGxiYWNrU3RhZ2UiOiJiZWZvcmUtZXhlY3V0ZSIsImNhbGxiYWNrRmFpbHVyZUFjdGlvbiI6Imlnbm9yZSIsImNhbGxiYWNrVXJsIjoiaHR0cHM6Ly9hdXRoLWNkbi51Yy5jbi9vdXRlci9vc3MvY2hlY2twbGF5IiwiY2FsbGJhY2tCb2R5Ijoie1wiaG9zdFwiOiR7aHR0cEhlYWRlci5ob3N0fSxcInNpemVcIjoke3NpemV9LFwicmFuZ2VcIjoke2h0dHBIZWFkZXIucmFuZ2V9LFwicmVmZXJlclwiOiR7aHR0cEhlYWRlci5yZWZlcmVyfSxcImNvb2tpZVwiOiR7aHR0cEhlYWRlci5jb29raWV9LFwibWV0aG9kXCI6JHtodHRwSGVhZGVyLm1ldGhvZH0sXCJpcFwiOiR7Y2xpZW50SXB9LFwib2JqZWN0XCI6JHtvYmplY3R9LFwic3BcIjoke3g6c3B9LFwidG9rZW5cIjoke3g6dG9rZW59LFwidHRsXCI6JHt4OnR0bH0sXCJjbGllbnRfdG9rZW5cIjoke3F1ZXJ5U3RyaW5nLmNsaWVudF90b2tlbn19In0%3D&callback-var=eyJ4OnNwIjoiMzc4IiwieDp0b2tlbiI6IjItNDg5YWE1Yzc3OGE1MWY3MTc1ODVhMjUzY2U4MjkwYTEtOC0xLTIwNDgtNDNiNGMxMzk4NTBjNDkyZWFmMTIwNTA2MWI5NjZiYTEtYTk2MDhlNTFlMjUwMDJlNTkyODJkYzNmMjA3MGU0M2EiLCJ4OnR0bCI6IjIxNjAwIn0%3D
cookie: __pus=77641f2139b914c29ed2b0caf246723dAAQbjDyR/fi1Z9YqqWbfO2qPZYeRTrFSC2P30uuWJwtY2ZwwQTRsEPHJKc9nuPnrXfQxir+0N8K/mVfr7SIwGc2t;
user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) quark-cloud-drive/2.5.20 Chrome/100.0.4896.160 Electron/18.3.5.4-b478491100 Safari/537.36 Channel/pckk_other_ch
### quark_pan
# 我用夸克网盘分享了「C# Shell (C# Offline Compiler)_2.5.16.apk」点击链接即可保存。打开「夸克APP」无需下载在线播放视频畅享原画5倍速支持电视投屏。
#链接https://pan.quark.cn/s/8f816f506409
# step1 获取stoken
POST https://drive-pc.quark.cn/1/clouddrive/share/sharepage/token?pr=ucpro&fr=pc
accept: application/json, text/plain, */*
content-type: application/json
{"pwd_id":"8f816f506409","passcode":""}
### quark_pan
# step2 获取fid
https://drive-pc.quark.cn/1/clouddrive/share/sharepage/detail?pr=ucpro&fr=pc&pwd_id=8f816f506409&stoken=JX6p1XFG5hD2VaUJFxazvE72u9TuhcKiXd81%2BXaFFsI%3D&pdir_fid=0&force=0&_page=1&_size=50&_fetch_banner=1&_fetch_share=1&_fetch_total=1&_sort=file_type:asc,updated_at:desc
### quark_pan
https://drive-pc.quark.cn/1/clouddrive/auth/pc/flush?pr=ucpro&fr=pc
cookie: __pus=77641f2139b914c29ed2b0caf246723dAAQbjDyR/fi1Z9YqqWbfO2qPZYeRTrFSC2P30uuWJwtY2ZwwQTRsEPHJKc9nuPnrXfQxir+0N8K/mVfr7SIwGc2t;
###
https://www.ecpan.cn/drive/fileextoverrid.do?chainUrlTemplate=https:%2F%2Fwww.ecpan.cn%2Fweb%2F%23%2FyunpanProxy%3Fpath%3D%252F%2523%252Fdrive%252Foutside&data=aa0cae0164d8885e6d35826b5b2901eckbWJBalM&parentId=-1
###
# @no-redirect
GET http://127.0.0.1:6400/parser?url=https://www.ecpan.cn/web/#/yunpanProxy?path=%2F%23%2Fdrive%2Foutside&data=81027a5c99af5b11ca004966c945cce6W9Bf2&isShare=
# https://www.ecpan.cn/drive/fileextoverrid.do?chainUrlTemplate=https://www.ecpan.cn/web/#/yunpanProxy?path=%2F%23%2Fdrive%2Foutside&data=aa0cae0164d8885e6d35826b5b2901eckbWJBalM&parentId=-1
###
# @no-redirect
GET http://127.0.0.1:6400/ec/aa0cae0164d8885e6d35826b5b2901eckbWJBalM1
###
GET http://127.0.0.1:6400/json/ec/aa0cae0164d8885e6d35826b5b2901eckbWJBalM
###
# @no-redirect
GET http://127.0.0.1:6400/uc/33197dd53ace4
###
GET http://127.0.0.1:6400/json/uc/33197dd53ace4
###
# @no-redirect
GET http://127.0.0.1:6400/parser?url=https://fast.uc.cn/s/33197dd53ace4

View File

@@ -0,0 +1,29 @@
# https://fast.uc.cn/s/33197dd53ace4
### UCpan
https://fast.uc.cn/api/info?st=&fr=pc&pr=UCBrowser
### UCpan 第一步 获取stoken POST json传入pwd_id(分享id),passcode(分享密码)
POST https://pc-api.uc.cn/1/clouddrive/share/sharepage/token?entry=ft&fr=pc&pr=UCBrowser
content-type: application/json
{"pwd_id":"33197dd53ace4","passcode":"","share_for_transfer":true}
### UCpan 第二步 获取fid,share_fid_token GET传参pwd_id,passcode,stoken
https://pc-api.uc.cn/1/clouddrive/transfer_share/detail?pwd_id=33197dd53ace4&passcode=&stoken=oPz47hsgQXQdDYimsP4kBMi8aLv40X378IZOiBsnfLU%3D
content-type: application/json
### UCpan 第二步获取下载链接 POST json传入fids(fid),pwd_id,stoken,fids_token(share_fid_token)
POST https://pc-api.uc.cn/1/clouddrive/file/download?entry=ft&fr=pc&pr=UCBrowser
content-type: application/json
{
"fids": [
"54c3cd90ed3e45119bb96ed99a562d40"
],
"pwd_id": "33197dd53ace4",
"stoken": "oPz47hsgQXQdDYimsP4kBMi8aLv40X378IZOiBsnfLU=",
"fids_token": [
"ff9f5b5c94df9d08c8dd3b7948fc5e20"
]
}

View File

@@ -0,0 +1,61 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!-- 日志自定义颜色 -->
<!-- https://logback.qos.ch/manual/layouts.html#coloring -->
<!--日志文件主目录:这里${user.home}为当前服务器用户主目录-->
<property name="LOG_HOME" value="logs"/>
<!--日志文件名称这里spring.application.name表示工程名称-->
<property name="LOGBACK_DEFAULT" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n"/>
<property name="CUSTOMER_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} %magenta([%t]) %highlight(%-5p) %yellow(${PID:-}) %cyan(%-40.40logger{39}) : %green(%m%n)"/>
<property name="CUSTOMER_PATTERN2" value="%d{yyyy-MM-dd HH:mm:ss.SSS} %highlight(%-5level) -> %magenta([%15.15thread]) %cyan(%-40.40logger{39}) : %msg%n"/>
<!--配置日志文件(File)-->
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!--设置策略-->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--日志文件路径:这里%d{yyyyMMdd}表示按天分类日志-->
<FileNamePattern>${LOG_HOME}/%d{yyyyMMdd}/run.log</FileNamePattern>
<!--日志保留天数-->
<MaxHistory>15</MaxHistory>
</rollingPolicy>
<!--设置格式-->
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!--格式化输出:%d表示日期%thread表示线程名%-5level级别从左显示5个字符宽度%msg日志消息%n是换行符-->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
<!-- 或者使用默认配置 -->
<!--<pattern>${FILE_LOG_PATTERN}</pattern>-->
<charset>utf8</charset>
</encoder>
<!--日志文件最大的大小-->
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<MaxFileSize>100MB</MaxFileSize>
</triggeringPolicy>
</appender>
<!-- 将文件输出设置成异步输出 -->
<appender name="ASYNC-FILE" class="ch.qos.logback.classic.AsyncAppender">
<!-- 不丢失日志.默认的,如果队列的80%已满,则会丢弃TRACT、DEBUG、INFO级别的日志 -->
<discardingThreshold>0</discardingThreshold>
<!-- 更改默认的队列的深度,该值会影响性能.默认值为256 -->
<queueSize>256</queueSize>
<!-- 添加附加的appender,最多只能添加一个 -->
<appender-ref ref="FILE"/>
</appender>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<!--格式化输出:%d表示日期%thread表示线程名%-5level级别从左显示5个字符宽度%msg日志消息%n是换行符-->
<pattern>${CUSTOMER_PATTERN2}</pattern>
</encoder>
</appender>
<logger name="io.netty" level="warn"/>
<logger name="io.vertx" level="info"/>
<logger name="com.zaxxer.hikari" level="info"/>
<root level="debug">
<appender-ref ref="STDOUT"/>
<!-- <appender-ref ref="FILE"/>-->
</root>
</configuration>

View File

@@ -0,0 +1,30 @@
# 反向代理
server-name: Vert.x-proxy-server(v4.1.2)
#proxy:
# - listen: 8085
# # 404的路径
# 404: webroot/real-html/index.html
# static:
# path: /
## add-headers:
## x-token: ABC
# root: webroot/real-html/
# index: realIndex
# location:
# - path: /real/
# origin: 127.0.0.1:8088
# - path: /api/
# origin: 127.0.0.1:7070/demo/
#
# - listen: 8086
# static:
# path: /t2/
# root: webroot/test/
# index: sockTest.html
# location:
# - path: /real/
# origin: 127.0.0.1:8088
# sock:
# - path: /real/
# origin: 127.0.0.1:8088