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

Java 串接微信公眾平台:自訂選單建立、查詢與刪除完整教學

     編輯:Java 相關知識

前言

微信公眾平台自訂選單是商家與用戶互動的重要入口。本文提供基於 Java 原生 HttpURLConnection 的完整實現,涵蓋 Access Token 獲取、選單結構定義、創建/刪除 API 調用,無第三方 SDK 依賴,適合快速整合至現有系統。

核心流程

  1. 獲取 Access Token:憑 AppID/AppSecret 調用 /cgi-bin/token,Token 有效期 2 小時,建議快取並定時刷新。
  2. 構建選單 JSON:按微信規範定義按鈕類型(click/view/miniprogram)、名稱、Key/URL、子按鈕(最多 3 個一級、每級 5 個子按鈕)。
  3. 調用創建/刪除接口:POST 請求帶 JSON Body 創建,GET 請求刪除。

完整工具類實現

package com.example.wechat;

import org.json.JSONObject;
import java.io.*;
import java.net.*;

public class WeChatMenuUtil {
    // 請替換為實際的 AppID 與 AppSecret
    private static final String APP_ID = "your_app_id";
    private static final String APP_SECRET = "your_app_secret";
    private static final String TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s";
    private static final String CREATE_MENU_URL = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=%s";
    private static final String DELETE_MENU_URL = "https://api.weixin.qq.com/cgi-bin/menu/delete?access_token=%s";

    // 獲取 Access Token(建議生產環境加入快取與刷新機制)
    private static String getAccessToken() throws IOException {
        String url = String.format(TOKEN_URL, APP_ID, APP_SECRET);
        HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();
        conn.setRequestMethod("GET");
        conn.setConnectTimeout(30000);
        conn.setReadTimeout(30000);

        try (InputStream is = conn.getInputStream();
             BufferedReader br = new BufferedReader(new InputStreamReader(is, "UTF-8"))) {
            StringBuilder sb = new StringBuilder();
            String line;
            while ((line = br.readLine()) != null) sb.append(line);
            JSONObject json = new JSONObject(sb.toString());
            if (json.has("errcode")) {
                throw new RuntimeException("獲取 Token 失敗: " + json.getString("errmsg"));
            }
            return json.getString("access_token");
        }
    }

    // 創建自訂選單
    public static String createMenu(String menuJson) throws IOException {
        String token = getAccessToken();
        String url = String.format(CREATE_MENU_URL, token);
        return sendPost(url, menuJson);
    }

    // 刪除自訂選單
    public static String deleteMenu() throws IOException {
        String token = getAccessToken();
        String url = String.format(DELETE_MENU_URL, token);
        return sendGet(url);
    }

    // 通用 POST 發送 JSON
    private static String sendPost(String urlStr, String jsonBody) throws IOException {
        HttpURLConnection conn = (HttpURLConnection) new URL(urlStr).openConnection();
        conn.setRequestMethod("POST");
        conn.setDoOutput(true);
        conn.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
        conn.setConnectTimeout(30000);
        conn.setReadTimeout(30000);

        try (OutputStream os = conn.getOutputStream()) {
            os.write(jsonBody.getBytes("UTF-8"));
        }
        return readResponse(conn);
    }

    // 通用 GET
    private static String sendGet(String urlStr) throws IOException {
        HttpURLConnection conn = (HttpURLConnection) new URL(urlStr).openConnection();
        conn.setRequestMethod("GET");
        conn.setConnectTimeout(30000);
        conn.setReadTimeout(30000);
        return readResponse(conn);
    }

    private static String readResponse(HttpURLConnection conn) throws IOException {
        try (InputStream is = conn.getInputStream();
             BufferedReader br = new BufferedReader(new InputStreamReader(is, "UTF-8"))) {
            StringBuilder sb = new StringBuilder();
            String line;
            while ((line = br.readLine()) != null) sb.append(line);
            return sb.toString();
        }
    }

    // 測試主程式
    public static void main(String[] args) {
        try {
            // 定義選單結構(JSON 字串或用 JSONObject 構建)
            String menuJson = "{\"button\":[" +
                "{\"type\":\"click\",\"name\":\"今日歌曲\",\"key\":\"V1_MUSIC\"}," +
                "{\"type\":\"click\",\"name\":\"歌手簡介\",\"key\":\"V1_SINGER\"}," +
                "{\"name\":\"菜單\",\"sub_button\":[" +
                    "{\"type\":\"view\",\"name\":\"搜尋\",\"url\":\"https://www.soso.com/\"}," +
                    "{\"type\":\"view\",\"name\":\"視頻\",\"url\":\"https://v.qq.com/\"}," +
                    "{\"type\":\"click\",\"name\":\"贊一下\",\"key\":\"V1_GOOD\"}" +
                "]}" +
            "]}";

            System.out.println("創建選單結果: " + createMenu(menuJson));
            // System.out.println("刪除選單結果: " + deleteMenu());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

選單 JSON 結構規範重點

  • 一級按鈕:最多 3 個,名稱 ≤ 16 字節(漢字算 2 字節)。
  • 子按鈕:每個一級最多 5 個,名稱 ≤ 40 字節。
  • 類型:
    • click:點擊推事件,需配合 Key,後端接收事件推送處理。
    • view:跳轉 URL,需在公眾號後台配置網頁授權域名。
    • miniprogram:跳小程序,需綁定小程序 AppID。

常見問題與最佳實踐

  • Token 管理:切勿每次調用都獲取 Token。使用單例/靜態變量快取,背景執行緒提前 5 分鐘刷新。
  • 錯誤碼處理:微信返回 {"errcode":0,"errmsg":"ok"} 表示成功。常見錯誤:40001 (Token 無效)、45009 (頻率限制)、46003 (選單結構錯誤)。
  • 編碼:請求與響應均強制 UTF-8,避免中文亂碼。
  • HTTPS:生產環境需信任微信 CA 證書,若 JDK 版本較舊可能需導入憑證。

總結

本工具類封裝了微信選單管理的核心 HTTP 交互,代碼精簡、依賴極少(僅 org.json),可直接拷貝至專案使用。實際上線時,請務必完善 Token 快取、異常重試、日誌監控,確保高可用性。

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