Initial project

This commit is contained in:
Timi
2025-07-14 11:50:02 +08:00
parent 9f1260ec32
commit 51a23c2178
10 changed files with 491 additions and 94 deletions

View File

@ -0,0 +1,25 @@
package com.imyeyu.network;
import org.apache.hc.client5.http.fluent.Form;
import org.apache.hc.core5.http.NameValuePair;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* HashMap 构建 {@link org.apache.hc.client5.http.fluent.Form} 参数列表
*
* @author 夜雨
* @since 2025-06-26 15:41
*/
public class FormMap<K, V> extends HashMap<K, V> {
public List<NameValuePair> build() {
Form form = Form.form();
for (Map.Entry<K, V> item : entrySet()) {
form.add(item.getKey().toString(), item.getValue().toString());
}
return form.build();
}
}

View File

@ -0,0 +1,164 @@
package com.imyeyu.network;
import com.imyeyu.java.bean.CallbackArg;
import com.imyeyu.utils.Calc;
import com.imyeyu.utils.Encoder;
import java.awt.Desktop;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.URI;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
/**
* @author 夜雨
* @version 2024-03-29 17:22
*/
public class Network {
/**
* 使用默认浏览器打开 URL 地址
*
* @param url 地址
*/
public static void openURIInBrowser(String url) {
try {
Desktop dp = Desktop.getDesktop();
if (dp.isSupported(Desktop.Action.BROWSE)) {
dp.browse(URI.create(Encoder.url(url)));
}
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* TCP 测试 IP 连接延时(异步)
*
* @param ip IP
* @param callback 结果回调,单位毫秒(超时 8 秒或失败回参为 -1
*/
public static void pingAsync(String ip, CallbackArg<Integer> callback) {
pingAsync(ip, 8000, callback);
}
/**
* TCP 测试 IP 连接延时(异步)
*
* @param ip IP
* @param timeout 超时限制,单位毫秒
* @param callback 结果回调,单位毫秒(超时或失败回参为 -1
*/
public static void pingAsync(String ip, int timeout, CallbackArg<Integer> callback) {
new Thread(() -> callback.handler(ping(ip, timeout))).start();
}
/**
* TCP 测试 IP 连接延时同步8 秒连接失败返回 -1
*
* @param ip IP
* @return 延时值,毫秒
*/
public static int ping(String ip) {
return ping(ip, 8000);
}
/**
* TCP 测试 IP 连接延时(同步)
*
* @param ip IP
* @param timeout 超时限制,单位毫秒
* @return 延时值,毫秒
*/
public static int ping(String ip, int timeout) {
try {
long s = System.currentTimeMillis();
InetAddress address = InetAddress.getByName(ip);
boolean isReachable = address.isReachable(timeout);
if (isReachable) {
return Calc.floor((System.currentTimeMillis() - s) * .5);
}
return -1;
} catch (Exception e) {
return -1;
}
}
/**
* 检测一个端口是否被占用
*
* @param port 端口
* @return 为 true 时表示已被占用
*/
public static boolean isBusyPort(int port) {
if (port < 1 || 65535 < port) {
throw new IllegalArgumentException("port must between with [1, 65535]");
}
try {
Socket socket = new Socket();
socket.connect(new InetSocketAddress("127.0.0.1", port), 500);
socket.close();
return true;
} catch (Exception e) {
return false;
}
}
/**
* 获取 URI 文件名
*
* @param uri URI 路径
* @return 文件名
*/
public static String uriFileName(String uri) {
int parSp = uri.indexOf("?");
if (parSp != -1) {
uri = uri.substring(0, parSp);
}
int sp = uri.lastIndexOf("/");
if (sp == -1) {
return uri;
}
return uri.substring(sp + 1);
}
/**
* 获取 URI 简易的文件名,不含格式
*
* @param uri URI 路径
* @return 文件名
*/
public static String simpleURIFileName(String uri) {
String fileName = uriFileName(uri);
int dot = fileName.lastIndexOf(".");
if (dot != -1) {
return fileName.substring(0, dot);
}
return fileName;
}
/**
* 获取 URI 文件扩展名
*
* @param uri URI 路径
* @return 扩展名
*/
public static String uriFileExtension(String uri) {
String fileName = uriFileName(uri);
int dot = fileName.lastIndexOf(".");
if (dot != -1) {
return fileName.substring(dot + 1);
}
return "";
}
public static String getFileDownloadHeader(String fileName) throws UnsupportedEncodingException {
String fallbackFileName = fileName.replaceAll("[^\\x00-\\x7F]", "_");
String encodedFileName = URLEncoder.encode(fileName, StandardCharsets.UTF_8).replace("+", "%20");
return "attachment; filename=\"%s\"; filename*=UTF-8''%s".formatted(fallbackFileName, encodedFileName);
}
}

View File

@ -0,0 +1,81 @@
package com.imyeyu.network;
import com.imyeyu.io.IO;
import org.apache.hc.client5.http.fluent.Request;
import org.apache.hc.client5.http.fluent.Response;
import org.apache.hc.core5.http.HttpEntity;
import org.apache.hc.core5.http.io.HttpClientResponseHandler;
import org.apache.hc.core5.http.io.entity.EntityUtils;
import javax.naming.NoPermissionException;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Path;
/**
* 封装 {@link org.apache.hc.client5.http.fluent.Request} 计算返回进度
*
* @author 夜雨
* @since 2025-06-26 13:03
*/
public class ProgressiveRequest {
private final Request request;
private final ProgressiveCallback callback;
private ProgressiveRequest(Request request, ProgressiveCallback callback) {
this.request = request;
this.callback = callback;
}
public static ProgressiveRequest wrap(Request request, ProgressiveCallback callback) {
return new ProgressiveRequest(request, callback);
}
public void toFile(Path outputPath) throws IOException, NoPermissionException {
processResponse(request.execute(), IO.getOutputStream(outputPath.toFile()));
}
public byte[] asBytes() throws IOException {
ByteArrayOutputStream os = new ByteArrayOutputStream();
processResponse(request.execute(), os);
return os.toByteArray();
}
private void processResponse(Response response, OutputStream os) throws IOException {
response.handleResponse((HttpClientResponseHandler<Void>) resp -> {
HttpEntity entity = resp.getEntity();
if (entity == null) {
throw new IOException("not found response entity");
}
int code = resp.getCode();
if (400 <= code) {
throw new IOException("response error: %s".formatted(code));
}
long length = entity.getContentLength();
IO.toOutputStream(entity.getContent(), os, new IO.OnWriteCallback() {
@Override
public boolean handler(long total, long now) {
return callback.handler(length, total, now);
}
});
EntityUtils.consume(entity);
return null;
});
}
/**
*
*
* @author 夜雨
* @since 2025-06-26 15:18
*/
public interface ProgressiveCallback {
boolean handler(long total, long read, long now);
}
}