日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java 微信 菜单_java微信开发API第四步 微信自定义个性化菜单实现

發(fā)布時間:2024/4/11 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java 微信 菜单_java微信开发API第四步 微信自定义个性化菜单实现 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

微信如何實現(xiàn)自定義個性化菜單,下面為大家介紹

一、全局說明

詳細說明請參考前兩篇文章。

二、本文說明

本文分為五部分:

* 工具類AccessTokenUtils的封裝

* 自定義菜單和個性化菜單文檔的閱讀解析

* 菜單JSON的分析以及構建對應bean

* 自定義菜單的實現(xiàn)

* 個性化菜單的實現(xiàn)

微信自定義菜單所有類型菜單都給出演示

本文結束會給出包括本文前四篇文章的所有演示源碼

工具類AccessTokenUtils的封裝在上文中關于AccessToken的獲取和定時保存已經(jīng)詳細介紹過,此處直接給出處理過之后封裝的AccessTokenUtils,實現(xiàn)原理以及文檔閱讀不再給出。

AccessTokenUtils.java

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145package com.gist.utils;

import java.io.File;

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.InputStreamReader;

import java.net.URL;

import javax.net.ssl.HttpsURLConnection;

import com.gist.bean.Access_token;

import com.google.gson.Gson;

/**

* @author 高遠 郵箱:wgyscsf@163.com 博客 http://blog.csdn.net/wgyscsf

*? 編寫時期 2016-4-7 下午5:44:33

*/

public class AccessTokenUtils {

private static final long MAX_TIME =7200 *1000;// 微信允許最長Access_token有效時間(ms)

private static final String TAG ="WeixinApiTest";// TAG

private static final String APPID ="wx889b020b3666b0b8";// APPID

private static final String SECERT ="6da7676bf394f0a9f15fbf06027856bb";// 秘鑰

/*

* 該方法實現(xiàn)獲取Access_token、保存并且只保存2小時Access_token。如果超過兩個小時重新獲取;如果沒有超過兩個小時,直接獲取。該方法依賴

* :public static String getAccessToken();

*

* 思路:將獲取到的Access_token和當前時間存儲到file里,

* 取出時判斷當前時間和存儲里面的記錄的時間的時間差,如果大于MAX_TIME,重新獲取,并且將獲取到的存儲到file替換原來的內容

* ,如果小于MAX_TIME,直接獲取。

*/

// 為了調用不拋異常,這里全部捕捉異常,代碼有點長

public static String getSavedAccess_token() {

Gson gson = new Gson();// 第三方jar,處理json和bean的轉換

String mAccess_token = null;// 需要獲取的Access_token;

FileOutputStream fos = null;// 輸出流

FileInputStream fis = null;// 輸入流

File file = new File("temp_access_token.temp");// Access_token保存的位置

try {

// 如果文件不存在,創(chuàng)建

if (!file.exists()) {

file.createNewFile();

}

} catch (Exception e1) {

e1.printStackTrace();

}

// 如果文件大小等于0,說明第一次使用,存入Access_token

if (file.length() == 0) {

try {

mAccess_token = getAccessToken();// 獲取AccessToken

Access_token at = new Access_token();

at.setAccess_token(mAccess_token);

at.setExpires_in(System.currentTimeMillis() + "");// 設置存入時間

String json = gson.toJson(at);

fos = new FileOutputStream(file, false);// 不允許追加

fos.write((json).getBytes());// 將AccessToken和當前時間存入文件

fos.close();

return mAccess_token;

} catch (Exception e) {

e.printStackTrace();

}

} else {

// 讀取文件內容

byte[] b = new byte[2048];

int len = 0;

try {

fis = new FileInputStream(file);

len = fis.read(b);

} catch (IOException e1) {

// TODO Auto-generated catch block

e1.printStackTrace();

}

String mJsonAccess_token = new String(b, 0, len);// 讀取到的文件內容

Access_token access_token = gson.fromJson(mJsonAccess_token,

new Access_token().getClass());

if (access_token.getExpires_in() != null) {

long saveTime = Long.parseLong(access_token.getExpires_in());

long nowTime = System.currentTimeMillis();

long remianTime = nowTime - saveTime;

// System.out.println(TAG + "時間差:" + remianTime + "ms");

if (remianTime < MAX_TIME) {

Access_token at = gson.fromJson(mJsonAccess_token,

new Access_token().getClass());

mAccess_token = at.getAccess_token();

return mAccess_token;

} else {

mAccess_token = getAccessToken();

Access_token at = new Access_token();

at.setAccess_token(mAccess_token);

at.setExpires_in(System.currentTimeMillis() + "");

String json = gson.toJson(at);

try {

fos = new FileOutputStream(file, false);// 不允許追加

fos.write((json).getBytes());

fos.close();

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

return mAccess_token;

}

} else {

return null;

}

}

return mAccess_token;

}

/*

* 獲取微信服務器AccessToken。該部分和getAccess_token() 一致,不再加注釋

*/

public static String getAccessToken() {

+ APPID +"&secret=" + SECERT;

String reslut =null;

try {

URL reqURL =new URL(urlString);

HttpsURLConnection httpsConn = (HttpsURLConnection) reqURL

.openConnection();

InputStreamReader isr =new InputStreamReader(

httpsConn.getInputStream());

char[] chars =new char[1024];

reslut ="";

int len;

while ((len = isr.read(chars)) != -1) {

reslut +=new String(chars,0, len);

}

isr.close();

}catch (IOException e) {

e.printStackTrace();

}

Gson gson =new Gson();

Access_token access_token = gson.fromJson(reslut,

new Access_token().getClass());

if (access_token.getAccess_token() !=null) {

return access_token.getAccess_token();

}else {

return null;

}

}

}

自定義菜單和個性化菜單文檔的閱讀解析·自定義菜單

?自定義菜單創(chuàng)建接口

?自定義菜單查詢接口

?自定義菜單刪除接口

?自定義菜單事件推送

?個性化菜單接口

?獲取公眾號的菜單配置

·文檔地址:http://mp.weixin.qq.com/wiki/10/0234e39a2025342c17a7d23595c6b40a.html?·官網(wǎng)文檔給出這樣解釋:

* 自定義菜單接口可實現(xiàn)多種類型按鈕,如下:1、click:點擊事件...;2、view:跳轉事件...;3、...(關于自定義菜單)

* 接口調用請求說明 http請求方式:POST(請使用https協(xié)議) https://api.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN(關于自定義菜單)

* click和view的請求示例 {"button":[...]}? (關于自定義菜單)

* 參數(shù)說明...(關于自定義菜單)

* 創(chuàng)建個性化菜單http請求方式:POST(請使用https協(xié)議)https://api.weixin.qq.com/cgi-bin/menu/addconditional?access_token=ACCESS_TOKEN(關于個性化菜單)

* 請求示例: {"button":[...],"matchrule":{...}}(關于個性化菜單)

* 參數(shù)說明...(關于個性化菜單)

* 開發(fā)者可以通過以下條件來設置用戶看到的菜單(關于個性化菜單):

1、用戶分組(開發(fā)者的業(yè)務需求可以借助用戶分組來完成)

2、性別

3、手機操作系統(tǒng)

4、地區(qū)(用戶在微信客戶端設置的地區(qū))

5、語言(用戶在微信客戶端設置的語言)

·理解:

?又是熟悉的POST請求,但是,關于調用貌似說的含糊其辭,不太明白。只是知道我們需要使用“?access_token=ACCESS_TOKEN”這個參數(shù),這個參數(shù)我們在上篇文章已經(jīng)獲取到了。假如我們將微信文檔給的那個請求地址中“ACCESS_TOKEN”換成我們獲取到的自己的ACCESS_TOKEN,訪問該網(wǎng)址,會看到“{“errcode”:44002,”errmsg”:”empty post data hint: [Gdveda0984vr23]”}”。大概意思是,空的post請求數(shù)據(jù)。所以,我們要通過POST請求的形式傳遞參數(shù)給微信服務器,在文檔下面還給出了參數(shù)的格式:{“button”:[…]},所以,我們要按照該格式給微信服務器進行傳遞參數(shù)。

?關于參數(shù)說明,我們可以看到在自定義菜單創(chuàng)建中有七個參數(shù)。在個性化菜單接口中除去這七個參數(shù)之外,另外多個八個參數(shù)。簡單查看此部分文檔,我們可以了解到這個八個參數(shù)是為了個性化菜單做匹配篩選用的。

?現(xiàn)在,我們需要按照微信文檔的要求構造json通過post的請求向微信服務器發(fā)送這一串json數(shù)據(jù),json里面就包括我們創(chuàng)建的各種類型的按鈕事件。

菜單JSON的分析以及構建對應bean?自定義菜單json分析(不包括個性化菜單)。下面這段代碼是微信文檔給的示例。

click和view的請求示例

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27{

"button":[

{

"type":"click",

"name":"今日歌曲",

"key":"V1001_TODAY_MUSIC"

},

{

"name":"菜單",

"sub_button":[

{

"type":"view",

"name":"搜索",

},

{

"type":"view",

"name":"視頻",

},

{

"type":"click",

"name":"贊一下我們",

"key":"V1001_GOOD"

}]

}]

}

經(jīng)過分析我們可以看到這串json數(shù)據(jù)分為三層:“”button”:[{…},{…}]”、“[{…},{{“name”:菜單,”sub_button”:[{},{}]}]”、“{“type”:”view”,”name:”:”視頻”,”url”:”…”},{},{}”,可能看起來比較暈。

但是,如果我們能夠聯(lián)想起來現(xiàn)實中看到的微信菜單,就會好理解一點:一級:菜單(一個菜單),下包括一到三個父按鈕;二級:父按鈕(1~3個父按鈕),下包括一到五個子按鈕;三級:子按鈕(1~5個子按鈕)。

現(xiàn)在,我們可以看到json和我們理解的“菜單”可以一一對應起來了。現(xiàn)在重點是如何確認每一級的“級名”,在java中也就是對應的javabean對象。

同時,因為一級菜單下會有多個父按鈕,所以是一個List的形式。父按鈕下可能有多個子菜單,也是一個 List;但是,父按鈕也有可能也是一個單獨的可以響應的按鈕。是一個單獨的父按鈕對象。子按鈕就是一個單獨的子按鈕對象。

查看關于自定義菜單的參數(shù)說明,我們可以看到按鈕分為一級按鈕(“button”)和二級按鈕(“sub_button”)。還有一些公用的數(shù)據(jù)類型,例如:菜單響應類型(“type”)、菜單標題(“name”)、click類型的參數(shù)(“key”)、view類型的參數(shù)(“url”)、media_id類型和view_limited類型的參數(shù)(“media_id”)。

·數(shù)據(jù)抽象(沒有寫setter,getter):

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23//按鈕基類

public class BaseButton {

private String type;

private String name;

private String key;

private String url;

private String media_id;

}

//子按鈕

public class SonButtonextends BaseButton {

private String sub_button;

}

//父按鈕

public class FatherButtonextends BaseButton {

private String button;//可能直接一個父按鈕做響應

@SerializedName("sub_button")//為了保證Gson解析后子按鈕的名字是“sub_button”,具體用法請搜索

private List sonButtons;//可能有多個子按鈕

}

public class Menu {

@SerializedName("button")

private List fatherButtons;

}

以上是完整的自定義菜單的分析以及對應javabean的構建。

對于個性化菜單,如果查看該部分的文檔,會發(fā)現(xiàn)和自定義菜單大致相同,只是多個一個“配置”的json,格式是這樣的:{“button”:[…],”matchrule”:{…}}。

我們發(fā)現(xiàn),“匹配”這段json和“button”是同級的,分析和實現(xiàn)和上面基本等同,直接給出實現(xiàn)的javabean。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17//匹配的json對應的json

public class MatchRule {

private String group_id;

private String sex;

private String client_platform_type;

private String country;

private String province;

private String city;

private String language;

}

//修改Menu.java

public class Menu {

@SerializedName("button")

private List fatherButtons;

private MatchRule matchrule;

}

自定義菜單的實現(xiàn)?任務,我們實現(xiàn)所有微信按鈕響應類型:

任務(注釋:“m-0”表示父按鈕;“m-n”表示第m個父按鈕,第n個子按鈕(m,n≠0)):1-0:名字:click,響應點擊事件:點擊推事件?。2-0:名字:父按鈕2。2-1:名字:view,響應事件:跳轉網(wǎng)頁;2-2:名字:scancode_push,響應事件:掃碼推事件;2-3:名字:scancode_waitmsg,響應事件:掃碼推事件且彈出“消息接收中”提示框;2-4:名字:pic_sysphoto,響應事件

:彈出系統(tǒng)拍照發(fā)圖。2-5:名字:pic_photo_or_album,響應事件:彈出拍照或者相冊發(fā)圖。3-0:名字:父按鈕3。3-1:名字

:pic_weixin,響應事件:彈出微信相冊發(fā)圖器;3-2:名字:location_select,響應事件:彈出地理位置選擇器;3-3:名字:media_id,響應事件:下發(fā)消息(除文本消息);3-4:名字:view_limited,響應事件:跳轉圖文消息url。

實現(xiàn)源碼(引用的AccessTokenUtils.java在第一部分:工具類AccessTokenUtils的封裝)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141/*

* 創(chuàng)建自定義菜單。

*/

@Test

public void createCommMenu() {

String ACCESS_TOKEN = AccessTokenUtils.getAccessToken();// 獲取AccessToken,AccessTokenUtils是封裝好的類

// 拼接api要求的httpsurl鏈接

+ ACCESS_TOKEN;

try {

// 創(chuàng)建一個url

URL reqURL =new URL(urlString);

// 拿取鏈接

HttpsURLConnection httpsConn = (HttpsURLConnection) reqURL

.openConnection();

httpsConn.setDoOutput(true);

// 取得該連接的輸出流,以讀取響應內容

OutputStreamWriter osr =new OutputStreamWriter(

httpsConn.getOutputStream());

osr.write(getMenuJson());// 使用本類外部方法getMenuJson()

osr.close();

// 返回結果

InputStreamReader isr =new InputStreamReader(

httpsConn.getInputStream());

// 讀取服務器的響應內容并顯示

char[] chars =new char[1024];

String reslut ="";

int len;

while ((len = isr.read(chars)) != -1) {

reslut +=new String(chars,0, len);

}

System.out.println("返回結果:" + reslut);

isr.close();

}catch (IOException e) {

e.printStackTrace();

}

}

public String getMenuJson() {

Gson gson =new Gson();// json處理工具

Menu menu =new Menu();// 菜單類

List fatherButtons =new ArrayList();// 菜單中的父按鈕集合

// -----------

// 父按鈕1

FatherButton fb1 =new FatherButton();

fb1.setName("click");

fb1.setType("click");

fb1.setKey("10");

// -------------

// 父按鈕2

FatherButton fb2 =new FatherButton();

fb2.setName("父按鈕2");

List sonButtons2 =new ArrayList();// 子按鈕的集合

// 子按鈕2-1

SonButton sb21 =new SonButton();

sb21.setName("view");

sb21.setType("view");

// 子按鈕2-2

SonButton sb22 =new SonButton();

sb22.setName("scancode_push");

sb22.setType("scancode_push");

sb22.setKey("22");

// 子按鈕2-3

SonButton sb23 =new SonButton();

sb23.setName("scancode_waitmsg");

sb23.setType("scancode_waitmsg");

sb23.setKey("23");

// 子按鈕2-4

SonButton sb24 =new SonButton();

sb24.setName("pic_sysphoto");

sb24.setType("pic_sysphoto");

sb24.setKey("24");

// 子按鈕2-5

SonButton sb25 =new SonButton();

sb25.setName("pic_photo_or_album");

sb25.setType("pic_photo_or_album");

sb25.setKey("25");

// 添加子按鈕到子按鈕集合

sonButtons2.add(sb21);

sonButtons2.add(sb22);

sonButtons2.add(sb23);

sonButtons2.add(sb24);

sonButtons2.add(sb25);

// 將子按鈕放到2-0父按鈕集合

fb2.setSonButtons(sonButtons2);

// ------------------

// 父按鈕3

FatherButton fb3 =new FatherButton();

fb3.setName("父按鈕3");

List sonButtons3 =new ArrayList();

// 子按鈕3-1

SonButton sb31 =new SonButton();

sb31.setName("pic_weixin");

sb31.setType("pic_weixin");

sb31.setKey("31");

// 子按鈕3-2

SonButton sb32 =new SonButton();

sb32.setName("locatselect");

sb32.setType("location_select");

sb32.setKey("32");

// // 子按鈕3-3-->測試不了,因為要media_id。這需要調用素材id.

// SonButton sb33 = new SonButton();

// sb33.setName("media_id");

// sb33.setType("media_id");

// sb33.setMedia_id("???");

// // 子按鈕3-4-->測試不了,因為要media_id。這需要調用素材id.

// SonButton sb34 = new SonButton();

// sb34.setName("view_limited");

// sb34.setType("view_limited");

// sb34.setMedia_id("???");

// 添加子按鈕到子按鈕隊列

sonButtons3.add(sb31);

sonButtons3.add(sb32);

// sonButtons3.add(sb33);

// sonButtons3.add(sb34);

// 將子按鈕放到3-0父按鈕隊列

fb3.setSonButtons(sonButtons3);

// ---------------------

// 將父按鈕加入到父按鈕集合

fatherButtons.add(fb1);

fatherButtons.add(fb2);

fatherButtons.add(fb3);

// 將父按鈕隊列加入到菜單欄

menu.setFatherButtons(fatherButtons);

String json = gson.toJson(menu);

System.out.println(json);// 測試輸出

return json;

}

個性化菜單的實現(xiàn)?·任務:根據(jù)性別展示不同的按鈕顯示(可以根據(jù)性別、地區(qū)、分組手機操作系統(tǒng)等)

·修改代碼一,因為是不同的微信后臺實現(xiàn),所以接口也不一樣,不過還是POST請求,代碼不用改,只要替換原來urlString即可。

·修改代碼二,只要創(chuàng)建一個MatchRule,設置匹配規(guī)則,然后將matchrule加入到menu便可以完成匹配規(guī)則。

1

2

3

4

5

6// -----

// 從此處開始設置個性菜單

MatchRule matchrule =new MatchRule();

matchrule.setSex("2");// 男生

menu.setMatchrule(matchrule);

// ----

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

原文鏈接:http://blog.csdn.net/wgyscsf/article/details/51104855

如對本文有疑問,請?zhí)峤坏浇涣魃鐓^(qū),廣大熱心網(wǎng)友會為你解答!! 點擊進入社區(qū)

總結

以上是生活随笔為你收集整理的java 微信 菜单_java微信开发API第四步 微信自定义个性化菜单实现的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內容還不錯,歡迎將生活随笔推薦給好友。