How to implement a custom personalized menu, the following for you to introduce
I. Global description
For more information, please refer to the first two articles.
Second, this article explains
This article is divided into five parts:
* Tool Class Accesstokenutils encapsulation
* Reading analysis of custom menus and personalized menu documents
* Menu JSON analysis and build corresponding Bean
* Implementation of custom menus
* The realization of personalized menu
Micro-mail custom menu All types of menus are presented in the demo
The end of this article will give all the demo sources including the first four articles in this article
Encapsulation of Tool class Accesstokenutils
in the above about Accesstoken acquisition and time saving has been described in detail, here directly to deal with the package after the Accesstokenutils, implementation principles and document reading no longer give.
Accesstokenutils.java
Package 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 lofty </n> Mailbox:wgyscsf@163.com</n> Blog Http://blog.csdn.net/wgyscsf</n> * 2016-4-7 pm 5:
44:33/public class Accesstokenutils {private static final long Max_time = 7200 * 1000;//Micro-letter allows maximum Access_token effective time (ms) private static final String tag = "weixinapitest";/tag private static final String APPID = "Wx889b020b3666b0b8";//APP ID private static final String Secert = "6DA7676BF394F0A9F15FBF06027856BB";//Secret Key * * This method implements obtaining Access_token, saving, and saving only 2 hours a Ccess_token. If more than two hours to regain, if not more than two hours, direct access. The method relies on the *: public static String Getaccesstoken (); * * Thinking: Storing the acquired Access_token and current time in file, * when the time difference between the current time and the record in the store is taken out , if it is greater than max_time, gets it again, and replaces the acquired storage to file with the original content *,If less than max_time, direct gain. *///In order to call do not throw exceptions, here all catch exceptions, code a bit long public static String Getsavedaccess_token () {Gson Gson = new Gson ();//third party jar, processing JSON and be The conversion String Maccess_token = null;//The access_token to be obtained; FileOutputStream fos = null;//output stream FileInputStream FIS = nul l;//input Stream file = new file ("Temp_access_token.temp");//Access_token saved location try {//If file does not exist, create if (!file.exist
S ()) {file.createnewfile ();
} catch (Exception E1) {e1.printstacktrace (); //If the file size is equal to 0, the first use is to save Access_token if (file.length () = = 0) {try {Maccess_token = Getaccesstoken ();//Get ACC
Esstoken Access_token at = new Access_token ();
At.setaccess_token (Maccess_token);
At.setexpires_in (System.currenttimemillis () + "");/set to deposit time String JSON = Gson.tojson (at); FOS = new FileOutputStream (file, false);//Do not allow append Fos.write ((JSON). GetBytes ());//save Accesstoken and current time to file Fos.close ()
;
return maccess_token;
catch (Exception e) {e.printstacktrace (); }
else {//Read the contents of the file 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);//Read the contents of the file 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 + "time lag:" + 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);//Do not allow appending 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; /* * Get the Micro-server Accesstoken. This section is consistent with Getaccess_token (), no longer commented on/public static string Getaccesstoken () {String urlstring = "https://api.weixin.qq.c
Om/cgi-bin/token?grant_type=client_credential&appid= "+ 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;
}
}
}
Read resolution of custom menus and personalized menu documents
• Customize Menu
◦ Custom Menu Create interface
◦ custom menu query Interface
◦ Custom Menu Removal interface
◦ custom menu Event push
◦ Personalized Menu Interface
◦ Get public number menu configuration
Document address: http://mp.weixin.qq.com/wiki/10/0234e39a2025342c17a7d23595c6b40a.html
The official website document gives this explanation:
* Custom Menu interface can implement many types of buttons, as follows: 1, click the event ...; 2, view: Jump events ...; 3 、... (About custom menus)
* Interface Call Request Description HTTP request method: POST (use HTTPS protocol) Https://api.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_ TOKEN (about customizing Menus)
* Click and view request Example {"button": [...]} (about custom menu)
* Parameter description ... (About custom menus)
* Create personalized Menu HTTP request method: POST (use HTTPS protocol) https://api.weixin.qq.com/cgi-bin/menu/addconditional?access_token= Access_token ( about Personalized Menus)
* Request Example: {"button": [...], "matchrule": {...}} (About Personalized Menus)
* Parameter Description ... (About Personalized Menus)
* Developers can set the menu that the user sees (about personalized menus) by:
1, user group (Developer's business requirements can be done by user group)
2, Sex
3, mobile operating system
4, Region (user in the region of the micro-credit client settings)
5, Language (the language that the user sets in the micro-trust client)
Understand
◦ is also a familiar post request, but the call seems vague, not quite clear. Just know that we need to use the "? Access_token=access_token" parameter, which we have obtained in the previous article. If we replace "Access_token" in the request address of the micro-letter document with our own access_token, we will see "{" Errcode: 44002, "errmsg": "Empty post data hint : [Gdveda0984vr23] "}". The approximate meaning is that the null POST request data. So, we're going to pass the parameters to the micro-server by post request, and the format of the parameters is given below the document: {"button": [...]}, so we have to pass the parameters to the micro-trust server according to the format.
◦ about the parameter descriptions, we can see that there are seven parameters in the custom menu creation. In addition to the seven parameters in the personalized menu interface, there are eight more parameters. With a simple look at this section of the document, we can see that the eight parameters are used for matching filters for personalized menus.
◦ Now, we need to construct JSON to send this string of JSON data to the micro-server through post requests, including the various types of button events that we create, as required by the micro-letter documentation.
Analysis of menu JSON and construction of corresponding bean
Customize Menu JSON parsing (does not include personalized menus). The following code is an example of a micro-letter document.
Examples of requests for click and view
{"button": [{"Type": "click", "Name": "Today's Song", "Key": "V1001_today_music"
}, {' Name ': ' Menu ', ' Sub_button ': [{' type ': ' View ', ' name ': ' Search ', ' url ': ' http://www.soso.com/'},
{' type ': ' View ', ' name ': ' Video ', ' url ': ' http://v.qq.com/'}, {' Type ': ' Click ', ' name ': ' Praise us ', ' Key ': ' V1001_good '}]}
After analysis we can see that this string of JSON data is divided into three layers: "button: [{...},{...}] ', ' [{...},{{' name ': menu, ' Sub_button ': [{},{}]}] ', ' {' type ': ' View ', ' name : ": Video", "url": "..."},{},{} ", may look more faint."
But if we can relate to the micro-mail menu that we see in reality, you'll understand a little bit: first Level: Menu (a menu), below includes one to three parent buttons, two levels: the parent button (1~3 a parent button), the bottom includes one to five child buttons, level Three: A child button (1~5 child button).
Now we can see that JSON corresponds to the "menu" we understand. Now the focus is on how to confirm each level of "level name", in Java is the corresponding JavaBean object.
At the same time, because there are multiple parent buttons under a level menu, it is a form of list< parent menu >. There may be multiple submenus under the parent button, but also a list< submenu >; but the parent button may also be a separate, responsive button. is a separate parent button object. A child button is a separate Child button object.
View a description of the parameters for the custom menu, we can see that the button is divided into a Level button ("button") and a Level two button ("Sub_button"). There are also common data types, such as menu response type ("type"), menu caption ("name"), parameter of the click Type ("Key"), parameters of the view type ("url"), media_id type, and view_limited type parameters (" media_id ").
Data abstraction (without write setter,getter):
Button base class public class
Basebutton {
private String type;
private String name;
Private String key;
Private String URL;
Private String media_id;
}
Child button public
class Sonbutton extends Basebutton {
private String Sub_button;
}
Parent button Public
class Fatherbutton extends Basebutton {
Private String button;//can respond directly to a parent button
@ Serializedname ("Sub_button")//to ensure that Gson resolution after the name of the child button is "Sub_button", the specific use of the search for
private list<sonbutton> sonbuttons;//may have multiple child buttons
} public
class Menu {
@SerializedName ("button")
private list< Fatherbutton> fatherbuttons;
}
The above is the complete custom menu analysis and the corresponding JavaBean construction.
For personalized menus, if you look at the document for that section, you'll find that the custom menu is roughly the same, but it's just a few "config" json, which is the format: {"button": [...], "matchrule": {...}}.
We found that the "match" of the JSON and "button" is the same level, analysis and implementation and the above basic equivalence, directly give the implementation of the JavaBean.
Matching JSON corresponds to the 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;
}
Modify Menu.java public
class Menu {
@SerializedName ("button")
private list<fatherbutton> fatherbuttons;
Private Matchrule matchrule;
}
Implementation of custom Menus
Task, we implement all the micro-button response types:
Task (Note: "M-0" represents the parent button; "M-n" is the first M parent button, the Nth child button (m,n≠0)): 1-0: Name: Click, Response Click event: Click Push event. 2-0: First Name: Parent button 2. 2-1: Name: View, Response event: jump page; 2-2: Name: Scancode_push, Response event: Sweep code push event; 2-3: First Name: scancode_waitmsg, Response event: Sweep code push event and pop-up "message received" Prompt box ; 2-4: Name: Pic_sysphoto, responding to events
: Eject the system to take picture. 2-5: First Name: Pic_photo_or_album, Response event: Pop-up photo or album Hair map. 3-0: First Name: Parent button 3. 3-1: the name
: Pic_weixin, Response event: pop-up micro-letter photo album, 3-2: Name: Location_select, Response event: pop-up geographical selector; 3-3: Name: media_id, Response event: Send message (except text message); 3-4: Name: View_ Limited, Response event: Jump text message URL.
Implement source code (referenced Accesstokenutils.java in the first part: Tool class Accesstokenutils encapsulation)
* * Create a custom menu. */@Test public void Createcommmenu () {String Access_token = Accesstokenutils.getaccesstoken ();//Get Accesstoken,acces Stokenutils is a packaged class//stitching API required by Httpsurl link String urlstring = "Https://api.weixin.qq.com/cgi-bin/menu/create?access_
token= "+ Access_token;
try {//create a URL url requrl = new URL (urlstring);
Fetch link Httpsurlconnection httpsconn = (httpsurlconnection) requrl. OpenConnection ();
Httpsconn.setdooutput (TRUE);
Gets the output stream of the connection to read the response content OutputStreamWriter OSR = new OutputStreamWriter (Httpsconn.getoutputstream ());
Osr.write (Getmenujson ());//Use the external method of this class Getmenujson () Osr.close ();
return results InputStreamReader ISR = new InputStreamReader (Httpsconn.getinputstream ());
Read the server's response content and display char[] chars = new char[1024];
String Reslut = "";
int Len;
while (len = Isr.read (chars))!=-1) {Reslut + = new String (chars, 0, Len);
} System.out.println ("Return result:" + reslut);
Isr.close (); catch (IoexCeption e) {e.printstacktrace (); } public String Getmenujson () {Gson Gson = new Gson ()//JSON processing tool Menu Menu = new menu ();//Menu Class List<fathe rbutton> fatherbuttons = new arraylist<fatherbutton> ()//The parent button collection//-----------//Parent button in the menu 1 Fatherbutton fb1
= new Fatherbutton ();
Fb1.setname ("click");
Fb1.settype ("click");
Fb1.setkey ("10");
-------------//Parent button 2 Fatherbutton fb2 = new Fatherbutton ();
Fb2.setname ("Parent button 2"); list<sonbutton> sonButtons2 = new arraylist<sonbutton> ()///child button 2-1 Sonbutton sb21 = new Sonbutt
On ();
Sb21.setname ("View");
Sb21.seturl ("http://www.baidu.com");
Sb21.settype ("View");
Sub-button 2-2 Sonbutton sb22 = new Sonbutton ();
Sb22.setname ("Scancode_push");
Sb22.settype ("Scancode_push");
Sb22.setkey ("22");
Sub-button 2-3 Sonbutton sb23 = new Sonbutton ();
Sb23.setname ("scancode_waitmsg");
Sb23.settype ("scancode_waitmsg");
Sb23.setkey ("23"); Child button 2-4 Sonbutton sb24 = new SonbuTton ();
Sb24.setname ("Pic_sysphoto");
Sb24.settype ("Pic_sysphoto");
Sb24.setkey ("24");
Sub-button 2-5 Sonbutton sb25 = new Sonbutton ();
Sb25.setname ("Pic_photo_or_album");
Sb25.settype ("Pic_photo_or_album");
Sb25.setkey ("25");
Add Child button to Child button collection Sonbuttons2.add (SB21);
Sonbuttons2.add (SB22);
Sonbuttons2.add (SB23);
Sonbuttons2.add (SB24);
Sonbuttons2.add (SB25);
Place the child button in the 2-0 parent button collection fb2.setsonbuttons (SONBUTTONS2);
------------------//Parent button 3 Fatherbutton fb3 = new Fatherbutton ();
Fb3.setname ("parent button 3");
list<sonbutton> sonButtons3 = new arraylist<sonbutton> ();
Sub-button 3-1 Sonbutton sb31 = new Sonbutton ();
Sb31.setname ("Pic_weixin");
Sb31.settype ("Pic_weixin");
Sb31.setkey ("31");
Sub-button 3-2 Sonbutton sb32 = new Sonbutton ();
Sb32.setname ("Locatselect");
Sb32.settype ("Location_select");
Sb32.setkey ("32"); Child button 3-3--> test, because to media_id.
This requires a call to the material ID.
Sonbutton sb33 = new Sonbutton ();
Sb33.setname ("media_id"); Sb33.SetType ("media_id");
SB33.SETMEDIA_ID ("???"); Child button 3-4--> test, because to media_id.
This requires a call to the material ID.
Sonbutton sb34 = new Sonbutton ();
Sb34.setname ("view_limited");
Sb34.settype ("view_limited");
SB34.SETMEDIA_ID ("???");
Add a child button to the Child button queue Sonbuttons3.add (SB31);
Sonbuttons3.add (SB32);
Sonbuttons3.add (SB33);
Sonbuttons3.add (SB34);
Place the child button in the 3-0 parent button Queue Fb3.setsonbuttons (SONBUTTONS3);
---------------------//Add the parent button to the parent button collection Fatherbuttons.add (FB1);
Fatherbuttons.add (FB2);
Fatherbuttons.add (FB3);
Add the parent button queue to the menu bar menu.setfatherbuttons (fatherbuttons);
String json = Gson.tojson (menu);
SYSTEM.OUT.PRINTLN (JSON);//test output return JSON;
}
implementation of Personalized Menus
• Task: Show different buttons according to sex (according to sex, region, mobile phone operating system, etc.)
• Modify code One, because it is different micro-letter background implementation, so the interface is not the same, but still post request, the code does not have to change, as long as the replacement of the original urlstring can be.
Stitching API Required Httpsurl link
String urlstring = "https://api.weixin.qq.com/cgi-bin/menu/addconditional?access_token="
+ Access_token;
• Modify code two to create a matchrule, set a matching rule, and then add Matchrule to the menu to complete the matching rule.
-----
//Start setting up personalized menu
matchrule matchrule = new Matchrule ();
Matchrule.setsex ("2");//male
menu.setmatchrule (matchrule);
// ----
SOURCE Download: Http://xiazai.jb51.net/201606/yuanma/WeixinApi (jb51.net). rar
The above is the entire content of this article, I hope to help you learn, but also hope that we support the cloud habitat community.