🧑 博主簡介:CSDN博客專家,歷代文學網(PC端可以訪問:https://literature.sinhy.com/#/?__c=1000,移動端可微信小程序搜索“歷代文學”)總架構師,
15年
工作經驗,精通Java編程
,高并發設計
,Springboot和微服務
,熟悉Linux
,ESXI虛擬化
以及云原生Docker和K8s
,熱衷于探索科技的邊界,并將理論知識轉化為實際應用。保持對新技術的好奇心,樂于分享所學,希望通過我的實踐經歷和見解,啟發他人的創新思維。在這里,我希望能與志同道合的朋友交流探討,共同進步,一起在技術的世界里不斷學習成長。
技術合作請加本人wx(注明來自csdn):foreast_sea
在Java中對接微信公眾號并向指定關注用戶發送消息,主要依賴微信公眾號的消息模板功能。以下是關鍵步驟和代碼實現:
?? 一、核心前提條件
- 公眾號類型:需服務號或認證后的訂閱號(個人可用測試號)。
- 用戶關注:目標用戶必須已關注公眾號。
- 獲取用戶OpenID:每個用戶有唯一OpenID(通過網頁授權或后臺接口獲取)。
- 消息模板:在公眾號后臺申請模板消息,獲取
template_id
。
🔧 二、開發步驟與Java代碼實現
1. 服務器URL驗證(首次配置必做)
微信通過GET請求驗證服務器有效性,需實現校驗邏輯:
@WebServlet("/wx")
public class WxServlet extends HttpServlet {private static final String TOKEN = "your_token"; // 與公眾號配置的Token一致protected void doGet(HttpServletRequest request, HttpServletResponse response) {String signature = request.getParameter("signature");String timestamp = request.getParameter("timestamp");String nonce = request.getParameter("nonce");String echostr = request.getParameter("echostr");// 1. 排序并拼接Token、timestamp、nonceString[] arr = {TOKEN, timestamp, nonce};Arrays.sort(arr);String concatStr = String.join("", arr);// 2. SHA1加密String sha1 = DigestUtils.sha1Hex(concatStr); // Apache Commons Codec// 3. 校驗簽名if (sha1.equals(signature)) {response.getWriter().print(echostr); // 返回echostr表示驗證成功}}
}
注意:需使用內網穿透工具(如cpolar、natapp)將本地服務暴露為公網URL,供微信訪問。
2. 獲取Access Token
調用微信API獲取接口憑證(有效期2小時,需緩存):
public String getAccessToken() throws IOException {String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential"+ "&appid=APPID&secret=APPSECRET"; // 替換為實際AppID和AppSecretHttpClient client = HttpClient.newHttpClient();HttpRequest request = HttpRequest.newBuilder().uri(URI.create(url)).build();HttpResponse<String> response = client.send(request, BodyHandlers.ofString());JSONObject json = new JSONObject(response.body());return json.getString("access_token"); // 返回Token
}
優化:使用Redis緩存Token,避免頻繁調用。
3. 發送模板消息
構造JSON請求體,調用微信消息接口:
public void sendTemplateMessage(String openid, String templateId) throws IOException {// 1. 準備消息數據Map<String, Object> data = new HashMap<>();data.put("first", Map.of("value", "訂單通知", "color", "#173177"));data.put("orderNo", Map.of("value", "202408051234"));data.put("status", Map.of("value", "已發貨"));// 2. 構造完整請求體JSONObject body = new JSONObject();body.put("touser", openid);body.put("template_id", templateId);body.put("url", "https://yourdomain.com/order"); // 用戶點擊跳轉鏈接body.put("data", data);// 3. 調用接口String apiUrl = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + getAccessToken();HttpClient client = HttpClient.newHttpClient();HttpRequest request = HttpRequest.newBuilder().uri(URI.create(apiUrl)).header("Content-Type", "application/json").POST(HttpRequest.BodyPublishers.ofString(body.toString())).build();HttpResponse<String> response = client.send(request, BodyHandlers.ofString());System.out.println("發送結果:" + response.body()); // 解析errcode判斷成功與否
}
表:模板消息參數說明
參數 | 必填 | 說明 |
---|---|---|
touser | 是 | 用戶OpenID(如oOM-e52ersdi7a4wZTOQHUQOwGuw ) |
template_id | 是 | 模板ID(如AYZc280-hh7QeO5eM8Usl7SlD5wzQ_I8tQq1e9HlmhQ ) |
data | 是 | 模板內容,需與申請模板時的關鍵詞匹配(如first 、orderNo 等) |
url | 否 | 用戶點擊消息后跳轉的鏈接 |
?? 三、注意事項與常見問題
-
消息類型限制:
- 模板消息:適用于業務通知(如訂單狀態),需用戶觸發交互后7天內發送。
- 客服消息:用戶主動發送消息后48小時內可任意回復(無需模板)。
- 表:消息類型對比
特性 模板消息 客服消息 發送條件 需用戶觸發交互 用戶主動發消息后 時效性 7天內 48小時內 內容格式 固定模板 自由文本/圖文
-
調試工具:
- 測試號申請:微信公眾平臺測試賬號。
- 內網穿透工具:cpolar(穩定)或natapp(免費)。
-
錯誤碼處理:
40001
:Access Token無效 → 重新獲取。41028
:FormID失效 → 檢查用戶交互是否超期。- 完整錯誤碼:微信全局錯誤碼文檔。
🚀 四、進階優化建議
-
使用SDK簡化開發
推薦WxJava封裝底層請求:// 示例:WxJava發送模板消息 WxMpService wxService = new WxMpServiceImpl(); wxService.setWxMpConfigStorage(new WxMpInMemoryConfigStorage()); // 設置AppID/Secret WxMpTemplateMessage message = WxMpTemplateMessage.builder().toUser(openid).templateId(templateId).build(); message.addData(new WxMpTemplateData("status", "已完成")); wxService.getTemplateMsgService().sendTemplateMsg(message);
-
消息安全與性能
- Token管理:使用Redis緩存Access Token,定時刷新避免超限(每日2000次)。
- 異步發送:將消息發送任務放入線程池,避免阻塞主業務邏輯。