升级剩余依赖并将 HttpClient 4 迁移到 5

- 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 相关异常。
This commit is contained in:
root
2026-09-14 14:23:23 +08:00
parent 4623fca8b0
commit d5b97b82a0
4 changed files with 42 additions and 41 deletions
+5 -12
View File
@@ -54,7 +54,7 @@
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.26</version>
<version>5.8.47</version>
</dependency>
<dependency>
@@ -63,15 +63,8 @@
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.14</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpmime</artifactId>
<version>4.5.14</version>
<groupId>org.apache.httpcomponents.client5</groupId>
<artifactId>httpclient5</artifactId>
</dependency>
<dependency>
@@ -82,7 +75,7 @@
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-compress</artifactId>
<version>1.26.1</version>
<version>1.28.0</version>
</dependency>
<dependency>
@@ -99,7 +92,7 @@
<dependency>
<groupId>com.github.pengrad</groupId>
<artifactId>java-telegram-bot-api</artifactId>
<version>7.9.1</version>
<version>10.1.0</version>
</dependency>
<dependency>
@@ -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<String> temp = new ArrayList<>();
if (statusCode == 200) {
@@ -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<String> 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("上游返回为空");
@@ -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()))) {