微信開發學習總結(四)——自定義選單——自定義選單建立介面
阿新 • • 發佈:2018-12-13
一、自定義選單建立介面說明
自定義選單能夠幫助公眾號豐富介面,讓使用者更好更快地理解公眾號的功能。開啟自定義選單後,公眾號介面如圖所示:
請注意: ①自定義選單最多包括3個一級選單,每個一級選單最多包含5個二級選單。 ②一級選單最多4個漢字,二級選單最多7個漢字,多出來的部分將會以“…”代替。 ③建立自定義選單後,選單的重新整理策略是,在使用者進入公眾號會話頁或公眾號profile頁時,如果發現上一次拉取選單的請求在5分鐘以前,就會拉取一下選單,如果選單有更新,就會重新整理客戶端的選單。測試時可以嘗試取消關注公眾賬號後再次關注,則可以看到建立後的效果。
自定義選單介面可實現多種型別按鈕,如下:
介面呼叫請求說明
click和view的請求示例
{ "button":[ { "type":"click", "name":"今日歌曲", "key":"V1001_TODAY_MUSIC" }, { "name":"選單", "sub_button":[ { "type":"view", "name":"搜尋", "url":"http://www.soso.com/" }, { "type":"miniprogram", "name":"wxa", "url":"http://mp.weixin.qq.com", "appid":"wx286b93c14bbf93aa", "pagepath":"pages/lunar/index" }, { "type":"click", "name":"贊一下我們", "key":"V1001_GOOD" }] }] }
其他新增按鈕型別的請求示例
{
"button": [
{
"name": "掃碼",
"sub_button": [
{
"type": "scancode_waitmsg",
"name": "掃碼帶提示",
"key": "rselfmenu_0_0",
"sub_button": [ ]
},
{
"type": "scancode_push",
"name": "掃碼推事件",
"key": "rselfmenu_0_1",
"sub_button": [ ]
}
]
},
{
"name": "發圖",
"sub_button": [
{
"type": "pic_sysphoto",
"name": "系統拍照發圖",
"key": "rselfmenu_1_0",
"sub_button": [ ]
},
{
"type": "pic_photo_or_album",
"name": "拍照或者相簿發圖",
"key": "rselfmenu_1_1",
"sub_button": [ ]
},
{
"type": "pic_weixin",
"name": "微信相簿發圖",
"key": "rselfmenu_1_2",
"sub_button": [ ]
}
]
},
{
"name": "傳送位置",
"type": "location_select",
"key": "rselfmenu_2_0"
},
{
"type": "media_id",
"name": "圖片",
"media_id": "MEDIA_ID1"
},
{
"type": "view_limited",
"name": "圖文訊息",
"media_id": "MEDIA_ID2"
}
]
}
引數說明
引數 | 是否必須 | 說明 |
---|---|---|
button | 是 | 一級選單陣列,個數應為1~3個 |
sub_button | 否 | 二級選單陣列,個數應為1~5個 |
type | 是 | 選單的響應動作型別,view表示網頁型別,click表示點選型別,miniprogram表示小程式型別 |
name | 是 | 選單標題,不超過16個位元組,子選單不超過60個位元組 |
key | click等點選型別必須 | 選單KEY值,用於訊息介面推送,不超過128位元組 |
url | view、miniprogram型別必須 | 網頁 連結,使用者點選選單可開啟連結,不超過1024位元組。 type為miniprogram時,不支援小程式的老版本客戶端將開啟本url。 |
media_id | media_id型別和view_limited型別必須 | 呼叫新增永久素材介面返回的合法media_id |
appid | miniprogram型別必須 | 小程式的appid(僅認證公眾號可配置) |
pagepath | miniprogram型別必須 | 小程式的頁面路徑 |
返回結果
正確時的返回JSON資料包如下:
{"errcode":0,"errmsg":"ok"}
錯誤時的返回JSON資料包如下(示例為無效選單名長度):
{"errcode":40018,"errmsg":"invalid button name size"}
二、自定義選單實體類的封裝
接下來是對選單結構的封裝。因為我們是採用面向物件的程式設計方式,最終提交的json格式選單資料就應該是由物件直接轉換得到,而不是在程式程式碼中拼一大堆json資料。選單結構封裝的依據是公眾平臺API文件中給出的那一段json格式的選單結構,如下所示: 選單結構的封裝有多種方式,因人而異,我介紹一種。
package weixin.entity.menu;
/**
* @所屬類別:實體類
* @用途:微信公眾號開發中自定義選單-自定義選單建立介面(所有選單共有屬性)
* @author yilei
* @version:1.0
*/
public class Button {
private String type;//選單的響應型別
private String name;//選單標題
private Button[] sub_button;// 二級選單陣列
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Button[] getSub_button() {
return sub_button;
}
public void setSub_button(Button[] sub_button) {
this.sub_button = sub_button;
}
/**
* @param type
* @param name
* @param sub_button
*/
public Button(String type, String name, Button[] sub_button) {
this.type = type;
this.name = name;
this.sub_button = sub_button;
}
public Button(){
}
}
package weixin.entity.menu;
/**
* @所屬類別:實體類
* @用途:微信公眾號開發中自定義選單-自定義選單建立介面(view/clike/scancode_push/scancode_waitmsg/pic_sysphoto/pic_photo_or_album/pic_weixin,)
* @author yilei
* @version:1.0
*/
public class TypeButton extends Button{
private String key;//click等點選型別必須 選單KEY值,用於訊息介面推送,不超過128位元組
private String url;//view、miniprogram型別必須 網頁 連結,使用者點選選單可開啟連結,不超過1024位元組。 type為miniprogram時,不支援小程式的老版本客戶端將開啟本url。
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
}
package weixin.entity.menu;
/**
* @所屬類別:實體類
* @用途:微信公眾號開發中自定義選單-自定義選單建立介面(Menu類代表整個微信公眾號自定義選單)
* @author yilei
* @version:1.0
*/
public class Menu {
private Button[] button;//button 是 一級選單陣列,個數應為1~3個
public Button[] getButton() {
return button;
}
public void setButton(Button[] button) {
this.button = button;
}
/**
* @param button
*/
public Menu(Button[] button) {
this.button = button;
}
public Menu(){
}
}
三、自定義選單的建立
/**
* 組裝選單
* @return
*/
public static Menu initMenu(){
Menu menu = new Menu();
//---------選單1、點選型別選單-------------------//
TypeButton c1 = new TypeButton();
c1.setName("點選型別選單1");
c1.setType("click");
c1.setKey("1");
Button b1 = new Button();
b1.setName("選單標題1");
b1.setSub_button(new Button[]{c1});
//---------選單2,具有2個子選單(一個點選型別、一個是網頁型別) -------------------//
TypeButton c2 = new TypeButton();
c2.setName("點選型別選單1");
c2.setType("click");
c2.setKey("11");
TypeButton v1 = new TypeButton();
v1.setName("點選網頁型別1");
v1.setType("view");
v1.setUrl("http://www.baidu.com");
Button b2 = new Button();
b2.setName("選單標題2");
b2.setSub_button(new Button[]{c2,v1});
//---------選單3,具有5個子選單(scancode_push/scancode_waitmsg/pic_sysphoto/pic_photo_or_album/pic_weixin/location_select) -------------------//
TypeButton t1 = new TypeButton();
t1.setName("掃碼推事件");
t1.setType("scancode_push");
t1.setKey("scancode_push");
TypeButton t2 = new TypeButton();
t2.setName("掃碼帶提示");
t2.setType("scancode_waitmsg");
t2.setKey("scancode_waitmsg");
TypeButton t3 = new TypeButton();
t3.setName("系統拍照發圖");
t3.setType("pic_sysphoto");
t3.setKey("pic_sysphoto");
TypeButton t4 = new TypeButton();
t4.setName("拍照或者相簿發圖");
t4.setType("pic_photo_or_album");
t4.setKey("pic_photo_or_album");
TypeButton t5 = new TypeButton();
t5.setName("微信相簿發圖");
t5.setType("pic_weixin");
t5.setKey("pic_weixin");
TypeButton t6 = new TypeButton();
t6.setName("傳送位置");
t6.setType("location_select");
t6.setKey("location_select");
Button b3 = new Button();
b3.setName("選單標題3");
b3.setSub_button(new Button[]{t1,t2,t3,t4,t5});
menu.setButton(new Button[]{b1,b2,b3});//
return menu;
}
/**
* 建立選單
* @param token(ACCESS_TOKEN)
* @param menu(已經轉換為json格式的Meun型別的字串)
* @return result =0,表示建立成功,否則失敗
*/
public static int createMenu(String token,String menu){
int errcode = 0;
String url = WeiXin.MENU_CREATE.replace("ACCESS_TOKEN", token);
JSONObject jsonObject = doPostStr(url, menu);
if(jsonObject != null){
errcode = jsonObject.getInt("errcode");
}
return errcode;
}
/**
* 發起Http請求, 通過POST方式訪問網路用到的方法
* @param url,請求的URL地址
* @return 響應後的字串
*/
public static JSONObject doPostStr(String url,String outstr){
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
JSONObject jsonObject = null;
try {
httpPost.setEntity(new StringEntity(outstr, "UTF-8"));
HttpResponse response = httpClient.execute(httpPost);
HttpEntity entity = response.getEntity();
String result=EntityUtils.toString(entity,"UTF-8");
jsonObject = JSONObject.fromObject(result);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return jsonObject;
}
/**
* 自定義選單-自定義建立選單介面
*/
public static final String MENU_CREATE="https://api.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN";
/**
* @變數類別 自定義選單介面可實現多種型別按鈕
* @變數含義 點選推事件
*/
public static final String MENU_CLICK="click";
/**
* @變數類別 自定義選單介面可實現多種型別按鈕
* @變數含義 跳轉URL
*/
public static final String MENU_VIEW="view";
/**
* @變數類別 自定義選單介面可實現多種型別按鈕
* @變數含義 掃碼推事件
*/
public static final String MENU_SCANCODE_PUSH="scancode_push";
/**
* @變數類別 自定義選單介面可實現多種型別按鈕
* @變數含義 掃碼推事件且彈出“訊息接收中”提示框
*/
public static final String MENU_SCANCODE_WAITMSG="scancode_waitmsg";
/**
* @變數類別 自定義選單介面可實現多種型別按鈕
* @變數含義 彈出系統拍照發圖
*/
public static final String MENU_PIC_SYSPHOTO="pic_sysphoto";
/**
* @變數類別 自定義選單介面可實現多種型別按鈕
* @變數含義 彈出拍照或者相簿發圖
*/
public static final String MENU_PIC_PHOTO_OR_ALBUM="pic_photo_or_album";
/**
* @變數類別 自定義選單介面可實現多種型別按鈕
* @變數含義 彈出微信相簿發圖器
*/
public static final String MENU_PIC_WEIXIN="pic_weixin";
/**
* @變數類別 自定義選單介面可實現多種型別按鈕
* @變數含義 彈出地理位置選擇器
*/
public static final String MENU_LOCATION_SELECT="location_select";
/**
* @變數類別 自定義選單介面可實現多種型別按鈕
* @變數含義 下發訊息(除文字訊息)
*/
public static final String MENU_MEDIA_ID="media_id";
/**
* @變數類別 自定義選單介面可實現多種型別按鈕
* @變數含義 跳轉圖文訊息URL
*/
public static final String MENU_VIEW_LIMITED="view_limited";
微信伺服器配置URL指向路徑
/**
* 處理微信伺服器發post請求發來的xml格式訊息
*/
@Override
public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
ServletContext context = getServletContext();
AccessToken accessToken = (AccessToken) context.getAttribute("access_token");
String menu = JSONObject.fromObject(WeiXinCheck.initMenu()).toString();
int errcode = WeiXinCheck.createMenu(accessToken.getAccessToken() , menu);
if(errcode==0){
System.out.println("選單建立成功!");
long startTime=System.currentTimeMillis(); //獲取開始時間
// TODO 接收、處理、響應由微信伺服器轉發的使用者傳送給公眾帳號的訊息
// 將請求、響應的編碼均設定為UTF-8(防止中文亂碼)
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
System.out.println("微信的post請求進入了本地伺服器了");
String result = "";
try {
Map<String,String> map = WeiXinCheck.parseXml(request);
System.out.println("微信公眾號要開始傳送訊息");
result = WeiXinCheck.buildResponseMessage(map);
if(result.equals("")){
result = "未正確響應";
}
} catch (Exception e) {
e.printStackTrace();
System.out.println("發生異常:"+ e.getMessage());
}
response.getWriter().println(result);
System.out.println( result) ;
long endTime=System.currentTimeMillis(); //獲取結束時間
System.out.println("程式執行時間: "+(endTime-startTime)+"ms");
}else{
System.out.println("選單建立失敗");
}
}
四、自定義選單的建立成功
如果已經關注了微信公眾號,可以先取消關注,重新掃描關注,就可以直接檢視最新選單