Initial project
This commit is contained in:
25
src/main/java/com/imyeyu/network/FormMap.java
Normal file
25
src/main/java/com/imyeyu/network/FormMap.java
Normal 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();
|
||||
}
|
||||
}
|
||||
164
src/main/java/com/imyeyu/network/Network.java
Normal file
164
src/main/java/com/imyeyu/network/Network.java
Normal 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);
|
||||
}
|
||||
}
|
||||
81
src/main/java/com/imyeyu/network/ProgressiveRequest.java
Normal file
81
src/main/java/com/imyeyu/network/ProgressiveRequest.java
Normal 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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user