首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

微信公眾號開發:模板消息發送完整實戰(Java 版,含 JSON 封裝、AccessToken 管理、用戶列表分頁獲取)

     編輯:Java 綜合教學

業務場景

服務號需主動向關注用戶推送交易提醒、發貨通知、預約確認等服務通知。微信規定:只能使用審核通過的模板,按模板 ID + 參數結構發送,不支持自定義內容隨意發送。

準備工作

  1. 微信公眾平台 → 功能 → 模板消息 → 添加模板 → 獲取 模板 ID。
  2. 配置服務器 IP 白名單、獲取 AppID/AppSecret。
  3. 引入 JSON 庫:net.sf.json-lib 或 Jackson/Gson(推薦 Jackson)。

核心接口

POST https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=ACCESS_TOKEN
Content-Type: application/json

{
  "touser": "OPENID",
  "template_id": "TEMPLATE_ID",
  "url": "https://example.com/detail",
  "topcolor": "#FF0000",
  "data": {
    "first": {"value": "尊敬的用戶,您有一筆新訂單", "color": "#173177"},
    "keyword1": {"value": "訂單號: 20240115001", "color": "#173177"},
    "keyword2": {"value": "金額: ¥299.00", "color": "#173177"},
    "remark": {"value": "請及時處理", "color": "#173177"}
  }
}

Java 實現核心代碼

1. 模板數據模型(以交易提醒為例)

public class TemplateMessage {
    private String touser;
    private String template_id;
    private String url;
    private String topcolor = "#FF0000";
    private Map data = new LinkedHashMap<>(); // 保持順序

    public static class DataItem {
        private String value;
        private String color;
        // getter/setter
    }
    // getter/setter + 靜態構建器方法
}

2. AccessToken 管理(單例 + 定時刷新)

public class AccessTokenManager {
    private static final String APP_ID = "your_appid";
    private static final String APP_SECRET = "your_secret";
    private static volatile String accessToken;
    private static volatile long expireTime = 0;

    public static synchronized String getAccessToken() {
        if (System.currentTimeMillis() < expireTime) return accessToken;
        String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + APP_ID + "&secret=" + APP_SECRET;
        String resp = HttpClientUtil.get(url);
        JSONObject json = JSONObject.fromObject(resp);
        accessToken = json.getString("access_token");
        expireTime = System.currentTimeMillis() + (json.getInt("expires_in") - 200) * 1000L; // 提前 200s 刷新
        return accessToken;
    }
}

3. 發送模板消息

public boolean sendTemplateMsg(TemplateMessage msg) {
    String url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + AccessTokenManager.getAccessToken();
    String json = JSONObject.fromObject(msg).toString();
    String resp = HttpClientUtil.postJson(url, json);
    JSONObject result = JSONObject.fromObject(resp);
    return result.getInt("errcode") == 0;
}

4. 獲取關注用戶列表(分頁,每次最多 10000)

public List getAllOpenIds() {
    List openIds = new ArrayList<>();
    String nextOpenId = null;
    do {
        String url = "https://api.weixin.qq.com/cgi-bin/user/get?access_token=" + AccessTokenManager.getAccessToken();
        if (nextOpenId != null) url += "&next_openid=" + nextOpenId;
        String resp = HttpClientUtil.get(url);
        JSONObject json = JSONObject.fromObject(resp);
        if (json.getInt("errcode") != 0) break;
        JSONArray arr = json.getJSONObject("data").getJSONArray("openid");
        for (int i = 0; i < arr.size(); i++) openIds.add(arr.getString(i));
        nextOpenId = json.getString("next_openid");
    } while (nextOpenId != null && !nextOpenId.isEmpty());
    return openIds;
}

5. 批量發送入口

public void broadcastTransactionNotice() {
    List openIds = getAllOpenIds();
    for (String openId : openIds) {
        String nickname = getUserNickname(openId); // 可選,個性化
        TemplateMessage msg = TemplateMessage.buildTransaction(openId, "TMPL_ID_123", "https://detail.url", nickname);
        boolean ok = sendTemplateMsg(msg);
        log.info("發送 {} -> {}", openId, ok ? "成功" : "失敗");
        // 限流:每秒不超過 100 條,避免封禁
        Thread.sleep(10);
    }
}

關鍵避坑指南

坑點解決
AccessToken 過期/並發刷新雙重檢查鎖 + volatile,或用 Redis 分布式鎖管理
模板參數名/順序不匹配嚴格對照公眾平台模板詳情,用 LinkedHashMap 保證序列化順序
data 字段 value 過長單個 value ≤ 1024 字節,超長會報錯 40058
用戶未關注/取消關注發送返回 43004,需捕獲並從本地庫移除
頻率限制接口調用上限:10萬/天(認證服務號),並發建議 ≤ 100/s
HTTPS 證書驗證生產環境必須啟用 SSL 驗證,勿關閉

擴展:使用成熟 SDK

手寫 HTTP/JSON 易出錯,推薦接入:

  • WxJava (github.com/Wechat-Group/WxJava) —— 全功能、活躍維護、Spring Boot Starter 就緒
  • weixin-java-mp —— 專注公眾號模塊

SDK 內置 AccessToken 自動刷新、模板消息構建器、異步發送、限流熔斷,生產級可靠。

總結

模板消息是服務號觸達用戶的核心通道。掌握「模板審核 → JSON 結構構建 → AccessToken 管理 → 分頁獲取用戶 → 限流發送」全鏈路,並遷移到成熟 SDK,才能構建穩定、合規、可擴展的消息通知系統。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved