From d5b97b82a02cb015a8d4cca0ee774cb69fd4e6a7 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 14 Sep 2026 14:23:23 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8D=87=E7=BA=A7=E5=89=A9=E4=BD=99=E4=BE=9D?= =?UTF-8?q?=E8=B5=96=E5=B9=B6=E5=B0=86=20HttpClient=204=20=E8=BF=81?= =?UTF-8?q?=E7=A7=BB=E5=88=B0=205?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - HttpClient 4.5.14 -> httpclient5 5.6.4(Boot 4.1.1 托管版本): HttpClient 4.x 最后一次发布是 2022-11,已 EOL,且 Boot 自 3.1 起不再管理它; httpmime 一并移除(httpclient5 已内置 multipart)。 代码迁移 3 个文件(LocalService、SubscriptionRefreshService、GalleryUtil): 包名 org.apache.http.* -> org.apache.hc.client5.http.*;HttpClient 5 用 response.getCode() 取代 response.getStatusLine().getStatusCode(); RequestConfig 的 socket 读超时改名 setSocketTimeout -> setResponseTimeout, 超时参数改为 Timeout.ofMilliseconds(...)。 MultipartEntityBuilder/EntityBuilder 仍在,仅换包名,行为不变。 - java-telegram-bot-api 7.9.1 -> 10.1.0(跨 3 个大版本)。本项目只用到 new TelegramBot(token)、new SendMessage(chatId, text)、bot.execute(msg), 已核对 10.1.0 的构造器与 execute 签名均兼容。 - hutool-all 5.8.26 -> 5.8.47;commons-compress 1.26.1 -> 1.28.0。 验证:mvn test 16 项全过(注意单测对 HTTP 是 mock,不能证明迁移后的真实网络路径); 另外做了针对性验证——隔离实例上 POST /personal/subBind/accounts/1/refresh 触发 真实上游下载,经迁移后的 httpclient5 成功取回 127,379 字节订阅并写入隔离缓存目录 (生产目录未被触碰);另用等价配置的 httpclient5 客户端实拉 https://example.com 返回 200 且正文可读。启动 5.09s、各接口正常、日志无 httpclient 相关异常。 --- pom.xml | 17 ++++------- .../lionwebsite/Service/LocalService.java | 12 ++++---- .../Service/SubscriptionRefreshService.java | 24 ++++++++------- .../lion/lionwebsite/Util/GalleryUtil.java | 30 +++++++++++-------- 4 files changed, 42 insertions(+), 41 deletions(-) diff --git a/pom.xml b/pom.xml index 0547115..96f1932 100644 --- a/pom.xml +++ b/pom.xml @@ -54,7 +54,7 @@ cn.hutool hutool-all - 5.8.26 + 5.8.47 @@ -63,15 +63,8 @@ - org.apache.httpcomponents - httpclient - 4.5.14 - - - - org.apache.httpcomponents - httpmime - 4.5.14 + org.apache.httpcomponents.client5 + httpclient5 @@ -82,7 +75,7 @@ org.apache.commons commons-compress - 1.26.1 + 1.28.0 @@ -99,7 +92,7 @@ com.github.pengrad java-telegram-bot-api - 7.9.1 + 10.1.0 diff --git a/src/main/java/com/lion/lionwebsite/Service/LocalService.java b/src/main/java/com/lion/lionwebsite/Service/LocalService.java index 4d12a7e..cb2aa23 100644 --- a/src/main/java/com/lion/lionwebsite/Service/LocalService.java +++ b/src/main/java/com/lion/lionwebsite/Service/LocalService.java @@ -9,11 +9,11 @@ import com.lion.lionwebsite.Util.CustomUtil; import com.lion.lionwebsite.Util.GalleryUtil; import lombok.Data; import lombok.extern.slf4j.Slf4j; -import org.apache.http.HttpEntity; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.client.HttpClients; +import org.apache.hc.client5.http.classic.methods.HttpGet; +import org.apache.hc.client5.http.impl.classic.CloseableHttpClient; +import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse; +import org.apache.hc.client5.http.impl.classic.HttpClients; +import org.apache.hc.core5.http.HttpEntity; import org.springframework.beans.factory.annotation.Value; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Service; @@ -228,7 +228,7 @@ public class LocalService{ httpResponse = httpClient.execute(httpGet); HttpEntity responseEntity = httpResponse.getEntity(); - int statusCode = httpResponse.getStatusLine().getStatusCode(); + int statusCode = httpResponse.getCode(); ArrayList temp = new ArrayList<>(); if (statusCode == 200) { diff --git a/src/main/java/com/lion/lionwebsite/Service/SubscriptionRefreshService.java b/src/main/java/com/lion/lionwebsite/Service/SubscriptionRefreshService.java index 1717075..d18f097 100644 --- a/src/main/java/com/lion/lionwebsite/Service/SubscriptionRefreshService.java +++ b/src/main/java/com/lion/lionwebsite/Service/SubscriptionRefreshService.java @@ -4,12 +4,13 @@ import com.lion.lionwebsite.Dao.normal.SubMapper; import com.lion.lionwebsite.Domain.SubscriptionAccount; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.apache.http.HttpEntity; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.client.HttpClients; +import org.apache.hc.client5.http.classic.methods.HttpGet; +import org.apache.hc.client5.http.config.RequestConfig; +import org.apache.hc.client5.http.impl.classic.CloseableHttpClient; +import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse; +import org.apache.hc.client5.http.impl.classic.HttpClients; +import org.apache.hc.core5.http.HttpEntity; +import org.apache.hc.core5.util.Timeout; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; @@ -27,8 +28,11 @@ import java.util.concurrent.locks.Lock; @RequiredArgsConstructor public class SubscriptionRefreshService { private static final CloseableHttpClient HTTP_CLIENT = HttpClients.custom() - .setDefaultRequestConfig(RequestConfig.custom().setConnectTimeout(5_000) - .setConnectionRequestTimeout(5_000).setSocketTimeout(15_000).build()) + .setDefaultRequestConfig(RequestConfig.custom() + .setConnectTimeout(Timeout.ofMilliseconds(5_000)) + .setConnectionRequestTimeout(Timeout.ofMilliseconds(5_000)) + // HttpClient 5 将 socket 读超时改名为 responseTimeout。 + .setResponseTimeout(Timeout.ofMilliseconds(15_000)).build()) .build(); private static final Pattern MULTIPLIER = Pattern.compile("(\\d+(?:\\.\\d+)?)x\\s*$", Pattern.CASE_INSENSITIVE); @@ -218,8 +222,8 @@ public class SubscriptionRefreshService { List download(String url) throws IOException { HttpGet get = new HttpGet(url); try (CloseableHttpResponse response = HTTP_CLIENT.execute(get)) { - if (response.getStatusLine().getStatusCode() != 200) - throw new IOException("上游 HTTP 状态码 " + response.getStatusLine().getStatusCode()); + if (response.getCode() != 200) + throw new IOException("上游 HTTP 状态码 " + response.getCode()); HttpEntity entity = response.getEntity(); if (entity == null) throw new IOException("上游返回为空"); diff --git a/src/main/java/com/lion/lionwebsite/Util/GalleryUtil.java b/src/main/java/com/lion/lionwebsite/Util/GalleryUtil.java index a456e47..8730eee 100644 --- a/src/main/java/com/lion/lionwebsite/Util/GalleryUtil.java +++ b/src/main/java/com/lion/lionwebsite/Util/GalleryUtil.java @@ -4,18 +4,19 @@ import tools.jackson.databind.JsonNode; import com.lion.lionwebsite.Domain.Gallery; import com.lion.lionwebsite.Domain.ImageKeyCache; import com.lion.lionwebsite.Exception.ResolutionNotMatchException; -import org.apache.http.HttpEntity; -import org.apache.http.client.config.RequestConfig; import java.nio.file.*; import java.util.concurrent.TimeUnit; -import org.apache.http.client.entity.EntityBuilder; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.entity.ContentType; -import org.apache.http.entity.mime.MultipartEntityBuilder; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.client.HttpClients; +import org.apache.hc.client5.http.classic.methods.HttpGet; +import org.apache.hc.client5.http.classic.methods.HttpPost; +import org.apache.hc.client5.http.config.RequestConfig; +import org.apache.hc.client5.http.entity.EntityBuilder; +import org.apache.hc.client5.http.entity.mime.MultipartEntityBuilder; +import org.apache.hc.client5.http.impl.classic.CloseableHttpClient; +import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse; +import org.apache.hc.client5.http.impl.classic.HttpClients; +import org.apache.hc.core5.http.ContentType; +import org.apache.hc.core5.http.HttpEntity; +import org.apache.hc.core5.util.Timeout; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; @@ -48,8 +49,11 @@ public class GalleryUtil { /** Reusable HTTP client —不要每次请求新建 */ private static final CloseableHttpClient httpClient = HttpClients.custom() - .setDefaultRequestConfig(RequestConfig.custom().setConnectTimeout(5_000) - .setConnectionRequestTimeout(5_000).setSocketTimeout(15_000).build()).build(); + .setDefaultRequestConfig(RequestConfig.custom() + .setConnectTimeout(Timeout.ofMilliseconds(5_000)) + .setConnectionRequestTimeout(Timeout.ofMilliseconds(5_000)) + // HttpClient 5 将 socket 读超时改名为 responseTimeout。 + .setResponseTimeout(Timeout.ofMilliseconds(15_000)).build()).build(); /** E-Hentai Cookie, injected from application.yaml via CustomBean */ private static String ehentaiCookie = ""; @@ -348,7 +352,7 @@ public class GalleryUtil { } try (httpResponse) { HttpEntity responseEntity = httpResponse.getEntity(); - int statusCode = httpResponse.getStatusLine().getStatusCode(); + int statusCode = httpResponse.getCode(); StringBuilder stringBuilder = new StringBuilder(); if (statusCode == 200 && responseEntity != null) { try (BufferedReader reader = new BufferedReader(new InputStreamReader(responseEntity.getContent()))) {