Java使用DefaultAlipayClient获取支付宝账单时如何配置正向代理?
结论
给 DefaultAlipayClient 配置正向代理时,需要在创建客户端时传入代理主机和端口。这是客户端级别的配置,会影响该客户端发出的所有支付宝 OpenAPI 请求,包括查询账单下载地址。
查询下载地址和下载账单文件是两次独立的 HTTP 请求。DefaultAlipayClient 中的代理只用于调用支付宝接口。取得 billDownloadUrl 后,如果下载账单文件也要经过代理,还需要为负责下载的 HTTP 客户端单独配置代理。
创建带代理的 DefaultAlipayClient
部分版本的支付宝 Java SDK 提供了包含 proxyHost 和 proxyPort 参数的构造方法,可以直接配置代理:
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
String gatewayUrl = "https://openapi.alipay.com/gateway.do";
String appId = "your_app_id";
String privateKey = "your_app_private_key";
String format = "json";
String charset = "UTF-8";
String alipayPublicKey = "your_alipay_public_key";
String signType = "RSA2";
String proxyHost = "127.0.0.1";
int proxyPort = 8080;
AlipayClient alipayClient = new DefaultAlipayClient(
gatewayUrl,
appId,
privateKey,
format,
charset,
alipayPublicKey,
signType,
proxyHost,
proxyPort
);
创建客户端后,可以正常调用账单下载地址查询接口:
import com.alipay.api.request.AlipayDataDataserviceBillDownloadurlQueryRequest;
import com.alipay.api.response.AlipayDataDataserviceBillDownloadurlQueryResponse;
AlipayDataDataserviceBillDownloadurlQueryRequest request =
new AlipayDataDataserviceBillDownloadurlQueryRequest();
request.setBizContent("""
{
"bill_type": "trade",
"bill_date": "2026-09-01"
}
""");
AlipayDataDataserviceBillDownloadurlQueryResponse response =
alipayClient.execute(request);
if (response.isSuccess()) {
String billDownloadUrl = response.getBillDownloadUrl();
System.out.println("账单下载地址:" + billDownloadUrl);
} else {
System.err.printf(
"查询失败,code=%s, subCode=%s, msg=%s, subMsg=%s%n",
response.getCode(),
response.getSubCode(),
response.getMsg(),
response.getSubMsg()
);
}
使用 AlipayConfig 配置
较新的 SDK 版本通常支持使用 AlipayConfig 创建客户端。如果项目依赖中的 AlipayConfig 提供了代理相关的 setter,也可以按下面的方式配置:
import com.alipay.api.AlipayClient;
import com.alipay.api.AlipayConfig;
import com.alipay.api.DefaultAlipayClient;
AlipayConfig config = new AlipayConfig();
config.setServerUrl("https://openapi.alipay.com/gateway.do");
config.setAppId("your_app_id");
config.setPrivateKey("your_app_private_key");
config.setFormat("json");
config.setCharset("UTF-8");
config.setAlipayPublicKey("your_alipay_public_key");
config.setSignType("RSA2");
config.setProxyHost("127.0.0.1");
config.setProxyPort(8080);
AlipayClient alipayClient = new DefaultAlipayClient(config);
支付宝 Java SDK 的不同版本在构造方法和 AlipayConfig 字段上可能有所不同。如果编译时找不到 setProxyHost、setProxyPort 或相应的构造方法,请以项目实际引入版本的 API 为准,不要混用不同版本的示例。
下载账单文件时也要配置代理
取得 billDownloadUrl 后,通常还要通过其他 HTTP 客户端下载 ZIP 文件。以下示例使用 JDK 11 及以上版本提供的 java.net.http.HttpClient:
import java.net.InetSocketAddress;
import java.net.ProxySelector;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.file.Path;
HttpClient downloadClient = HttpClient.newBuilder()
.proxy(ProxySelector.of(
new InetSocketAddress("127.0.0.1", 8080)
))
.followRedirects(HttpClient.Redirect.NORMAL)
.build();
HttpRequest downloadRequest = HttpRequest.newBuilder()
.uri(URI.create(billDownloadUrl))
.GET()
.build();
HttpResponse<Path> downloadResponse = downloadClient.send(
downloadRequest,
HttpResponse.BodyHandlers.ofFile(Path.of("alipay-bill.zip"))
);
if (downloadResponse.statusCode() < 200
|| downloadResponse.statusCode() >= 300) {
throw new IllegalStateException(
"账单下载失败,HTTP 状态码:" + downloadResponse.statusCode()
);
}
账单下载地址通常有时效限制,获取后应及时下载。不要长期记录完整的下载地址,因为 URL 中可能含有临时访问参数。
代理需要认证时
proxyHost 和 proxyPort 只能指定代理地址。能否直接配置代理用户名和密码,取决于支付宝 SDK 的版本及其底层 HTTP 实现。
如果代理要求认证,而当前 SDK 没有提供相关参数,不能直接把用户名和密码拼进 proxyHost。可以考虑以下方式:
- 使用无须认证的内网转发代理;
- 按照当前 SDK 提供的扩展方式配置底层 HTTP 客户端;
- 在可控环境中使用 JVM 的代理认证配置;
- 升级到支持自定义 HTTP 传输或代理认证的 SDK 版本。
是否需要升级,以及可以使用哪种扩展接口,要根据项目当前使用的 alipay-sdk-java 版本判断。
注意事项
- 支付宝网关使用 HTTPS,正向代理必须支持 HTTPS
CONNECT隧道。 - 代理服务器必须能够访问
openapi.alipay.com和账单下载地址对应的域名。 - 代理不能修改请求正文、字符编码或签名相关参数,否则可能导致验签失败。
- 应合理设置连接超时和读取超时,避免代理不可用时请求长时间阻塞。
- 如果多个业务共用同一个
DefaultAlipayClient,代理配置会影响该实例发出的所有请求。 - 生产环境中不要记录应用私钥、代理密码或完整的账单下载 URL。
备注:内容仅供参考。
