1
0
mirror of synced 2025-12-20 07:38:27 +08:00

🎨 添加 Apache HttpComponents Client 5.x 为可选的 http client

This commit is contained in:
altusea
2025-06-09 14:29:35 +08:00
committed by GitHub
parent bf35797b91
commit ccbfa98864
136 changed files with 2689 additions and 492 deletions

View File

@@ -1,11 +1,15 @@
package me.chanjar.weixin.open.executor;
import jodd.http.HttpConnectionProvider;
import jodd.http.ProxyInfo;
import me.chanjar.weixin.common.util.http.okhttp.OkHttpProxyInfo;
import me.chanjar.weixin.open.bean.CommonUploadMultiParam;
import me.chanjar.weixin.common.enums.WxType;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.common.util.http.RequestExecutor;
import me.chanjar.weixin.common.util.http.RequestHttp;
import me.chanjar.weixin.common.util.http.ResponseHandler;
import okhttp3.OkHttpClient;
import java.io.IOException;
@@ -33,15 +37,19 @@ public abstract class CommonUploadMultiRequestExecutor<H, P> implements RequestE
* @param requestHttp 请求信息
* @return 执行器
*/
@SuppressWarnings({"rawtypes", "unchecked"})
public static RequestExecutor<String, CommonUploadMultiParam> create(RequestHttp requestHttp) {
@SuppressWarnings("unchecked")
public static RequestExecutor<String, CommonUploadMultiParam> create(RequestHttp<?, ?> requestHttp) {
switch (requestHttp.getRequestType()) {
case APACHE_HTTP:
return new CommonUploadMultiRequestExecutorApacheImpl(requestHttp);
return new CommonUploadMultiRequestExecutorApacheImpl(
(RequestHttp<org.apache.http.impl.client.CloseableHttpClient, org.apache.http.HttpHost>) requestHttp);
case JODD_HTTP:
return new CommonUploadMultiRequestExecutorJoddHttpImpl(requestHttp);
return new CommonUploadMultiRequestExecutorJoddHttpImpl((RequestHttp<HttpConnectionProvider, ProxyInfo>) requestHttp);
case OK_HTTP:
return new CommonUploadMultiRequestExecutorOkHttpImpl(requestHttp);
return new CommonUploadMultiRequestExecutorOkHttpImpl((RequestHttp<OkHttpClient, OkHttpProxyInfo>) requestHttp);
case HTTP_COMPONENTS:
return new CommonUploadMultiRequestExecutorHttpComponentsImpl(
(RequestHttp<org.apache.hc.client5.http.impl.classic.CloseableHttpClient, org.apache.hc.core5.http.HttpHost>) requestHttp);
default:
throw new IllegalArgumentException("不支持的http执行器类型" + requestHttp.getRequestType());
}

View File

@@ -10,7 +10,6 @@ import me.chanjar.weixin.common.util.http.RequestHttp;
import me.chanjar.weixin.common.util.http.apache.Utf8ResponseHandler;
import me.chanjar.weixin.open.bean.CommonUploadMultiParam;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.Consts;
import org.apache.http.HttpHost;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpPost;
@@ -24,6 +23,7 @@ import org.springframework.util.CollectionUtils;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.List;
/**
@@ -50,7 +50,7 @@ public class CommonUploadMultiRequestExecutorApacheImpl extends CommonUploadMult
List<CommonUploadMultiParam.NormalParam> normalParams = param.getNormalParams();
if (!CollectionUtils.isEmpty(normalParams)) {
for (CommonUploadMultiParam.NormalParam normalParam : normalParams) {
entity.addPart(normalParam.getName(), new StringBody(normalParam.getValue(), ContentType.create("multipart/form-data", Consts.UTF_8)));
entity.addPart(normalParam.getName(), new StringBody(normalParam.getValue(), ContentType.MULTIPART_FORM_DATA.withCharset(StandardCharsets.UTF_8)));
}
}

View File

@@ -0,0 +1,89 @@
package me.chanjar.weixin.open.executor;
import lombok.Getter;
import me.chanjar.weixin.common.bean.CommonUploadData;
import me.chanjar.weixin.common.bean.CommonUploadParam;
import me.chanjar.weixin.common.enums.WxType;
import me.chanjar.weixin.common.error.WxError;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.common.util.http.RequestHttp;
import me.chanjar.weixin.common.util.http.hc.Utf8ResponseHandler;
import me.chanjar.weixin.open.bean.CommonUploadMultiParam;
import org.apache.commons.lang3.StringUtils;
import org.apache.hc.client5.http.classic.methods.HttpPost;
import org.apache.hc.client5.http.config.RequestConfig;
import org.apache.hc.client5.http.entity.mime.HttpMultipartMode;
import org.apache.hc.client5.http.entity.mime.InputStreamBody;
import org.apache.hc.client5.http.entity.mime.MultipartEntityBuilder;
import org.apache.hc.client5.http.entity.mime.StringBody;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.core5.http.ContentType;
import org.apache.hc.core5.http.HttpHost;
import org.springframework.util.CollectionUtils;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.List;
/**
* @author altusea
*/
public class CommonUploadMultiRequestExecutorHttpComponentsImpl extends CommonUploadMultiRequestExecutor<CloseableHttpClient, HttpHost> {
public CommonUploadMultiRequestExecutorHttpComponentsImpl(RequestHttp<CloseableHttpClient, HttpHost> requestHttp) {
super(requestHttp);
}
@Override
public String execute(String uri, CommonUploadMultiParam param, WxType wxType) throws WxErrorException, IOException {
HttpPost httpPost = new HttpPost(uri);
if (requestHttp.getRequestHttpProxy() != null) {
RequestConfig config = RequestConfig.custom().setProxy(requestHttp.getRequestHttpProxy()).build();
httpPost.setConfig(config);
}
if (param != null) {
MultipartEntityBuilder entity = MultipartEntityBuilder.create();
List<CommonUploadMultiParam.NormalParam> normalParams = param.getNormalParams();
if (!CollectionUtils.isEmpty(normalParams)) {
for (CommonUploadMultiParam.NormalParam normalParam : normalParams) {
entity.addPart(normalParam.getName(), new StringBody(normalParam.getValue(), ContentType.create("multipart/form-data", StandardCharsets.UTF_8)));
}
}
CommonUploadParam uploadParam = param.getUploadParam();
if (uploadParam != null) {
CommonUploadData data = uploadParam.getData();
InnerStreamBody part = new InnerStreamBody(data.getInputStream(), ContentType.DEFAULT_BINARY, data.getFileName(), data.getLength());
entity.addPart(uploadParam.getName(), part)
.setMode(HttpMultipartMode.EXTENDED);
}
httpPost.setEntity(entity.build());
}
String responseContent = requestHttp.getRequestHttpClient().execute(httpPost, Utf8ResponseHandler.INSTANCE);
if (StringUtils.isEmpty(responseContent)) {
throw new WxErrorException(String.format("上传失败,服务器响应空 url:%s param:%s", uri, param));
}
WxError error = WxError.fromJson(responseContent, wxType);
if (error.getErrorCode() != 0) {
throw new WxErrorException(error);
}
return responseContent;
}
/**
* 内部流 请求体
*/
@Getter
public static class InnerStreamBody extends InputStreamBody {
private final long contentLength;
public InnerStreamBody(final InputStream in, final ContentType contentType, final String filename, long contentLength) {
super(in, contentType, filename);
this.contentLength = contentLength;
}
}
}

View File

@@ -9,13 +9,12 @@ import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.SneakyThrows;
import me.chanjar.weixin.common.bean.CommonUploadData;
import me.chanjar.weixin.open.bean.CommonUploadMultiParam;
import me.chanjar.weixin.common.bean.CommonUploadParam;
import me.chanjar.weixin.common.enums.WxType;
import me.chanjar.weixin.common.error.WxError;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.common.util.http.RequestHttp;
import org.apache.http.Consts;
import me.chanjar.weixin.open.bean.CommonUploadMultiParam;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.content.StringBody;
import org.springframework.util.CollectionUtils;
@@ -47,7 +46,7 @@ public class CommonUploadMultiRequestExecutorJoddHttpImpl extends CommonUploadMu
List<CommonUploadMultiParam.NormalParam> normalParams = param.getNormalParams();
if (!CollectionUtils.isEmpty(normalParams)) {
for (CommonUploadMultiParam.NormalParam normalParam : normalParams) {
request.form(normalParam.getName(), new StringBody(normalParam.getValue(), ContentType.create("multipart/form-data", Consts.UTF_8)));
request.form(normalParam.getName(), new StringBody(normalParam.getValue(), ContentType.MULTIPART_FORM_DATA.withCharset(StandardCharsets.UTF_8)));
}
}

View File

@@ -0,0 +1,65 @@
package me.chanjar.weixin.open.executor;
import me.chanjar.weixin.common.enums.WxType;
import me.chanjar.weixin.common.error.WxError;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.common.util.fs.FileUtils;
import me.chanjar.weixin.common.util.http.RequestHttp;
import me.chanjar.weixin.common.util.http.hc.InputStreamResponseHandler;
import me.chanjar.weixin.common.util.http.hc.Utf8ResponseHandler;
import me.chanjar.weixin.open.bean.ma.WxMaQrcodeParam;
import org.apache.commons.lang3.StringUtils;
import org.apache.hc.client5.http.ClientProtocolException;
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.core5.http.ContentType;
import org.apache.hc.core5.http.Header;
import org.apache.hc.core5.http.HttpException;
import org.apache.hc.core5.http.HttpHost;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.UUID;
public class MaQrCodeHttpComponentsRequestExecutor extends MaQrCodeRequestExecutor<CloseableHttpClient, HttpHost> {
public MaQrCodeHttpComponentsRequestExecutor(RequestHttp<CloseableHttpClient, HttpHost> requestHttp) {
super(requestHttp);
}
@Override
public File execute(String uri, WxMaQrcodeParam qrcodeParam, WxType wxType) throws WxErrorException, IOException {
if (qrcodeParam != null && StringUtils.isNotBlank(qrcodeParam.getPagePath())) {
if (uri.indexOf('?') == -1) {
uri += '?';
}
uri += uri.endsWith("?")
? "path=" + URLEncoder.encode(qrcodeParam.getRequestPath(), "UTF-8")
: "&path=" + URLEncoder.encode(qrcodeParam.getRequestPath(), "UTF-8");
}
HttpGet httpGet = new HttpGet(uri);
if (requestHttp.getRequestHttpProxy() != null) {
RequestConfig config = RequestConfig.custom().setProxy(requestHttp.getRequestHttpProxy()).build();
httpGet.setConfig(config);
}
try (CloseableHttpResponse response = requestHttp.getRequestHttpClient().execute(httpGet);
InputStream inputStream = InputStreamResponseHandler.INSTANCE.handleResponse(response);) {
Header[] contentTypeHeader = response.getHeaders("Content-Type");
if (contentTypeHeader != null && contentTypeHeader.length > 0) {
// 出错
if (ContentType.TEXT_PLAIN.getMimeType().equals(ContentType.parse(contentTypeHeader[0].getValue()).getMimeType())) {
String responseContent = Utf8ResponseHandler.INSTANCE.handleResponse(response);
throw new WxErrorException(WxError.fromJson(responseContent, WxType.MiniApp));
}
}
return FileUtils.createTmpFile(inputStream, UUID.randomUUID().toString(), "jpg");
} catch (HttpException httpException) {
throw new ClientProtocolException(httpException.getMessage(), httpException);
}
}
}

View File

@@ -13,8 +13,6 @@ import me.chanjar.weixin.common.util.http.ResponseHandler;
import me.chanjar.weixin.common.util.http.okhttp.OkHttpProxyInfo;
import me.chanjar.weixin.open.bean.ma.WxMaQrcodeParam;
import okhttp3.OkHttpClient;
import org.apache.http.HttpHost;
import org.apache.http.impl.client.CloseableHttpClient;
/**
* 获得小程序体验QrCode图片 请求执行器.
@@ -35,16 +33,20 @@ public abstract class MaQrCodeRequestExecutor<H, P> implements RequestExecutor<F
}
@SuppressWarnings("unchecked")
public static RequestExecutor<File, WxMaQrcodeParam> create(RequestHttp<?, ?> requestHttp) throws WxErrorException {
public static RequestExecutor<File, WxMaQrcodeParam> create(RequestHttp<?, ?> requestHttp) {
switch (requestHttp.getRequestType()) {
case APACHE_HTTP:
return new MaQrCodeApacheHttpRequestExecutor((RequestHttp<CloseableHttpClient, HttpHost>) requestHttp);
return new MaQrCodeApacheHttpRequestExecutor(
(RequestHttp<org.apache.http.impl.client.CloseableHttpClient, org.apache.http.HttpHost>) requestHttp);
case JODD_HTTP:
return new MaQrCodeJoddHttpRequestExecutor((RequestHttp<HttpConnectionProvider, ProxyInfo>) requestHttp);
case OK_HTTP:
return new MaQrCodeOkhttpRequestExecutor((RequestHttp<OkHttpClient, OkHttpProxyInfo>) requestHttp);
case HTTP_COMPONENTS:
return new MaQrCodeHttpComponentsRequestExecutor(
(RequestHttp<org.apache.hc.client5.http.impl.classic.CloseableHttpClient, org.apache.hc.core5.http.HttpHost>) requestHttp);
default:
throw new WxErrorException("不支持的http框架");
throw new IllegalArgumentException("不支持的http执行器类型:" + requestHttp.getRequestType());
}
}