微信公眾平台自訂選單是商家與用戶互動的重要入口。本文提供基於 Java 原生 HttpURLConnection 的完整實現,涵蓋 Access Token 獲取、選單結構定義、創建/刪除 API 調用,無第三方 SDK 依賴,適合快速整合至現有系統。
/cgi-bin/token,Token 有效期 2 小時,建議快取並定時刷新。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();
}
}
}
click:點擊推事件,需配合 Key,後端接收事件推送處理。view:跳轉 URL,需在公眾號後台配置網頁授權域名。miniprogram:跳小程序,需綁定小程序 AppID。{"errcode":0,"errmsg":"ok"} 表示成功。常見錯誤:40001 (Token 無效)、45009 (頻率限制)、46003 (選單結構錯誤)。本工具類封裝了微信選單管理的核心 HTTP 交互,代碼精簡、依賴極少(僅 org.json),可直接拷貝至專案使用。實際上線時,請務必完善 Token 快取、異常重試、日誌監控,確保高可用性。