整體流程
- 獲取
access_token(有效期 2 小時,需緩存)
- 拉取用戶資訊(需
openid)
- 調用客服消息/模板消息接口主動推送
- 配置 HTTP 客戶端(連線池、HTTPS、代理、信任所有憑證)
核心工具類 WeixinAPIHelper
public class WeixinAPIHelper {
private static final String TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={0}&secret={1}";
private static final String USER_URL = "https://api.weixin.qq.com/cgi-bin/user/info?access_token={0}&openid={1}";
private static final String SEND_URL = "https://api.weixin.qq.com/cgi-bin/message/send?access_token={0}";
private HttpClient httpClient;
private Log log = LogFactory.getLog(getClass());
// 初始化 HTTP 客戶端(連線池、SSL 忽略驗證、代理支援)
public void initWebClient(String proxyHost, int proxyPort) { /* 見原碼 */ }
/** 獲取 access_token */
public String getAccessToken(String appid, String secret) {
String url = MessageFormat.format(TOKEN_URL, appid, secret);
String resp = executeHttpGet(url);
return JsonUtils.read(resp, "access_token");
}
/** 獲取用戶資訊 */
public WeixinOpenUser getUserInfo(String token, String openid) {
String url = MessageFormat.format(USER_URL, token, openid);
String resp = executeHttpGet(url);
JsonNode json = JsonUtils.read(resp);
if (json.get("openid") != null) {
WeixinOpenUser u = new WeixinOpenUser();
u.setOpenUserId(json.get("openid").asText());
u.setState(json.get("subscribe").asText());
if ("1".equals(u.getState())) {
u.setUserName(json.get("nickname").asText());
u.setSex(json.get("sex").asText());
u.setCity(json.get("city").asText());
u.setLanguage(json.get("language").asText());
}
return u;
}
return null;
}
/** 發送客服消息 */
public String sendMessage(String token, String msgJson) {
String url = MessageFormat.format(SEND_URL, token);
HttpPost post = new HttpPost(url);
post.setEntity(new StringEntity(msgJson, "UTF-8"));
return (String) httpClient.execute(post, new BasicResponseHandler());
}
private String executeHttpGet(String url) throws IOException {
return (String) httpClient.execute(new HttpGet(url), new BasicResponseHandler());
}
}
關鍵依賴
httpclient-4.2.3(或 4.5.x)
jackson-2.2.1(JSON 解析)
commons-lang(StringUtils)
消息 JSON 結構範例(文本消息)
{
"touser": "OPENID",
"msgtype": "text",
"text": { "content": "Hello from Java!" }
}
生產環境關鍵強化
| 問題 | 解決方案 |
| Token 重複請求 | 單例緩存 + 定時刷新(提前 5 分鐘),雙重檢查鎖 |
| HTTPS 憑證驗證 | 生產不可信任所有憑證,需導入微信根憑證或使用 JDK cacerts |
| 連線池調優 | setMaxTotal(100)、setDefaultMaxPerRoute(20)、啟用 Keep-Alive |
| 錯誤碼處理 | 解析 errcode,40001/42001 觸發 Token 刷新,45047 忽略(用戶未關注) |
| 異步發送 | 引入 CompletableFuture 或 MQ 解耦,避免阻塞業務執行緒 |
現代化替代:WxJava / weixin-java-tools
成熟開源 SDK,封裝 Token 管理、消息路由、事件處理、OAuth2、小程序/企業微信/開放平台全覆蓋,強烈建議新專案直接引用:
<dependency>
<groupId>com.github.binarywang</groupId>
<artifactId>weixin-java-mp</artifactId>
<version>4.6.0</version>
</dependency>
- 上一篇文章: Java 二分查找插入實作:Comparable 介面與有序集合維護
- 下一篇文章: Java DES 加密工具類:檔案與字串加解密完整實作(CBC/PKCS5Padding)
Copyright ©
程式碼之家 All Rights Reserved