文档编写:董尧
日期:2018.6.5
一、自定义菜单创建接口
二、自定义菜单查询接口
请求的URL地址
https://m.api.weibo.com/2/messages/menu/create.json
HTTP请求方式
POST请求
https://m.api.weibo.com/2/messages/menu/create.json?access_token=ACCESS_TOKEN&menus={ }
请求样式
https://m.api.weibo.com/2/messages/menu/create.json?access_token=ACCESS_TOKEN&menus={"button":+[{"type":+"click","name":+"获取优惠券","key":+"get_groupon"},{"type":+"click","name":+"查询客服电话","key":+"the_big_brother_need_your_phone"},{"name":+"菜单","sub_button":+[{"type":+"view","name":+"网上4S店","url":+"http://apps.weibo.com/1838358847/8rYu1uHD"},{"type":+"view","name":+"砍价团","url":+"http://apps.weibo.com/1838358847/8s1i6v74"},{"type":+"click","name":+"么么哒","key":+"memeda"}]}]}'
返回结果
//成功返回:
{
"result": true
}
// 失败返回
{
"request": "/2/messages/menu/create.json",
"error_code": 264XX,
"error": "error message."
}
接口请求参数
参数名称
值的类型
是否必填
说明描述
access_token
string
true
在账号Profile页--> 管理中心 --> 粉丝服务--> 高级功能--> 开发模式中获取,详细参考 获取粉丝服务平台开发接口的access token。
menus
string
true
需要创建的自定义菜单,必须为JSON做URLEncode后的字符串格式,具体内容格式详见注意事项。
官方实例:
{
"button": [
{
"type": "click",
"name": "获取优惠券",
"key": "get_groupon"
},
{
"type": "click",
"name": "查询客服电话",
"key": "the_big_brother_need_your_phone"
},
{
"name": "菜单",
"sub_button": [
{
"type": "view",
"name": "网上4S店",
"url": "http://apps.weibo.com/1838358847/8rYu1uHD"
},
{
"type": "view",
"name": "砍价团",
"url": "http://apps.weibo.com/1838358847/8s1i6v74"
},
{
"type": "click",
"name": "么么哒",
"key": "memeda"
}
]
}
]
}
参数
参数名称
值的类型
是否必填
说明描述
button
数组
true
一级菜单数组,个数应为1~3个
sub_button
数组
false
二级菜单数组,个数应为1~5个
type
String
false
(与二级菜单sub_button同级时可不填)菜单的响应动作类型,目前有click、view两种类型
name
String
true
菜单标题,不超过16个字节,子菜单不超过40个字节
Key
String
false
type为click时必填,菜单KEY值,用于消息接口推送,不超过128字节
url
String
flase
type为view时必填,网页链接,用户点击菜单可打开链接,不超过256字节
根据官方给的DEMO来看,我们可以先从内到外进行封装,即二级菜单(sub_button)封装,根据该个参数的说明描述,该个菜单的数量为1~5个,此时我们应该知道此处用到数组,即将sub_button用数组进行封装,一级菜单(button)的数量是1~3个,这里我们也应该用的是数组。下面我们进行创建,先在src目录下新建一个package,该个包的名称为:cn.json.weibo.menu
在该个包下创建一个类,该个类的名称是Sub_button,作用是用来进行封装二级菜单,
①Sub_button.java
package cn.json.weibo.menu; public class Sub_Button { private String type; private String name; private String url; private String key; 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 String getUrl() { return url; } public void setUrl(String url) { this.url = url; } public String getKey() { return key; } public void setKey(String key) { this.key = key; } }根据官方的DEMO来看,一级菜单下包含的属性有type,key,name,和二级菜单的数组sub_button[],所以我们根据这个来进行封装,封装后的Button类的代码如下:
②Button.java
package cn.json.weibo.menu; public class Button { //总体大框架 private Button[] button; private String type; private String name; private String key; private String url; //二级菜单框架 private Sub_Button[] sub_button; public Button[] getButton() { return button; } public void setButton(Button[] button) { this.button = 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 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; } public Sub_Button[] getSub_button() { return sub_button; } public void setSub_button(Sub_Button[] sub_button) { this.sub_button = sub_button; } }以上封装属性工作准备完成之后,接下来就是封装菜单,这里再新建一个CreateMenu的类
根据官方的开发文档,一级菜单最多有3个,二级菜单最多有5个,对此我们将一、二级菜单进行组合封装,
这里我用了两种方式
/** * 创建一级菜单,但是这个方法是一级菜单下含有二级菜单的方法 * @param name * @param sub_button * @return */ public static Button createOneMenu(String name,Sub_Button sub_button){ Sub_Button[] sub_bt = {sub_button}; Button bt_sb = new Button(); bt_sb.setName(name); bt_sb.setSub_button(sub_bt); return bt_sb; } public static Button createOneMenu(String name,Sub_Button sub_button,Sub_Button sub_button2){ Sub_Button[] sub_bt = {sub_button,sub_button2}; Button bt_sb = new Button(); bt_sb.setName(name); bt_sb.setSub_button(sub_bt); return bt_sb; } public static Button createOneMenu(String name,Sub_Button sub_button,Sub_Button sub_button2,Sub_Button sub_button3){ Sub_Button[] sub_bt = {sub_button,sub_button2,sub_button3}; Button bt_sb = new Button(); bt_sb.setName(name); bt_sb.setSub_button(sub_bt); return bt_sb; } public static Button createOneMenu(String name,Sub_Button sub_button,Sub_Button sub_button2,Sub_Button sub_button3,Sub_Button sub_button4){ Sub_Button[] sub_bt = {sub_button,sub_button2,sub_button3,sub_button4}; Button bt_sb = new Button(); bt_sb.setName(name); bt_sb.setSub_button(sub_bt); return bt_sb; } public static Button createOneMenu(String name,Sub_Button sub_button,Sub_Button sub_button2,Sub_Button sub_button3,Sub_Button sub_button4,Sub_Button sub_button5){ Sub_Button[] sub_bt = {sub_button,sub_button2,sub_button3,sub_button4,sub_button5}; Button bt_sb = new Button(); bt_sb.setName(name); bt_sb.setSub_button(sub_bt); return bt_sb; }
到此,菜单的封装工作结束,下边就是进行URLEncoder,和发送POST请求
这一步在src目录下创建一个包,该个包的名称是cn.json.commons,该个包是用来存放工具类。
首先,在这个包中创建一个CommonUtils类,并且在该个类中写一个进行URLEncoder处理的方法,现在的该个类的代码如下:
CommonUtils.java
/** * 将指定的字符串进行URLEcoder,并且返回处理后的字符串 * @param str * @return */ public static String getURLEncoderUTF8(String str){ try { str = URLEncoder.encode(str, "UTF-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return str; }由于,创建菜单需要进行发送POST请求,在这里我们单独写一个类用来处理这个过程。
在该个包下创建一个名为HTTPRequest和MyX509TrustManager的类
①HTTPRequest.java
package cn.json.commonutils; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.net.ConnectException; import java.net.HttpURLConnection; import java.net.URL; import java.security.SecureRandom; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.TrustManager; import com.alibaba.fastjson.JSONObject; public class HTTPRequest { /** * 该方法是进行POST或者是GET请求,并且返回一个JSONObject对象 * @param requestUrl 请求调用的URL地址 * @param requestMethod 请求的方法类型GET/POST * @param requestParam 请求的参数 * @return */ public static JSONObject httpRequest(String requestUrl,String requestMethod,String requestParam) { JSONObject jsonObject = null; StringBuffer buffer = new StringBuffer(); try { // 创建SSLContext对象,并使用我们指定的信任管理器初始化 TrustManager[] tm = { new MyX509TrustManager() }; SSLContext sslContext = SSLContext.getInstance("SSL","SunJSSE"); sslContext.init(null, tm, new SecureRandom()); // 从上述SSLContext对象中得到SSLSocketFactory对象 SSLSocketFactory ssf = sslContext.getSocketFactory(); URL url = new URL(requestUrl); HttpURLConnection httpUrlConn = (HttpURLConnection)url.openConnection(); ((HttpsURLConnection) httpUrlConn).setSSLSocketFactory(ssf); httpUrlConn.setDoOutput(true); httpUrlConn.setDoInput(true); httpUrlConn.setUseCaches(false); // 设置请求方式(GET/POST) httpUrlConn.setRequestMethod(requestMethod); if ("GET".equalsIgnoreCase(requestMethod)) httpUrlConn.connect(); // 当有数据需要提交时 if (null != requestParam) { OutputStream outputStream = httpUrlConn.getOutputStream(); // 注意编码格式,防止中文乱码 outputStream.write(requestParam.getBytes("UTF-8")); outputStream.close(); } // 将返回的输入流转换成字符串 InputStream inputStream = httpUrlConn.getInputStream(); InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8"); BufferedReader bufferedReader = new BufferedReader(inputStreamReader); String str = null; while ((str = bufferedReader.readLine()) != null) { buffer.append(str); } bufferedReader.close(); inputStreamReader.close(); // 释放资源 inputStream.close(); inputStream = null; httpUrlConn.disconnect(); jsonObject = JSONObject.parseObject(buffer.toString()); }catch (ConnectException ce) { System.out.println("微博服务器连接超时!"); }catch (Exception e) { System.out.println("HTTPS请求错误,错误信息:\n" + e.getMessage()); } return jsonObject; } }②MyX509TrustManager.java
package cn.json.commonutils; import java.net.Socket; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import javax.net.ssl.SSLEngine; import javax.net.ssl.X509ExtendedTrustManager; public class MyX509TrustManager extends X509ExtendedTrustManager { public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException { } public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException { } public X509Certificate[] getAcceptedIssuers() { return null; } public void checkClientTrusted(X509Certificate[] chain, String authType, Socket socket) throws CertificateException { } public void checkClientTrusted(X509Certificate[] chain, String authType, SSLEngine engine) throws CertificateException { } public void checkServerTrusted(X509Certificate[] chain, String authType, Socket socket) throws CertificateException { } public void checkServerTrusted(X509Certificate[] chain, String authType, SSLEngine engine) throws CertificateException { } }最后,写一个主方法进行测试,主方法的代码如下:
main()
public static void main(String[] args) { Button button1 = createOneMenu("click", "获取菜单", "getmenu"); Button button2 = createOneMenu("click", "测试二", "jihji"); //Sub_Button sub1 = createTwoMenu("view", "测试", "http://www.worldyao.cn/WeChat"); Button button3 = createOneMenu("二级测试",createTwoMenu("view", "测试", "http://www.worldyao.cn/WeChat", null),createTwoMenu("view", "测试", "http://www.worldyao.cn/WeChat",null)); //菜单封装 Button[] button = packageOneMenu(button1, button2, button3); Button btgroup = new Button(); btgroup.setButton(button); //将实体类转换成JSON字符串 String str = JSONObject.toJSONString(btgroup); str = CommonUtils.getURLEncoderUTF8(str); System.out.println(str); String url = "https://m.api.weibo.com/2/messages/menu/create.json?"; System.out.println(url); String pam = "access_token=xxxxxxxxxxxxxxxxxx&menus=" + str; JSONObject js = HTTPRequest.httpRequest(url, "POST", pam); System.out.println(js.toJSONString()); }返回结果:
{
"result":true,
"menu":{
"button":[
{
"name":"获取菜单",
"id":4247867901937670,
"type":"click",
"key":"getmenu",
"content":{
"data":"",
"text":"",
"type":0
}
},
{
"name":"测试二",
"id":4247867902201598,
"type":"click",
"key":"jihji",
"content":{
"data":"",
"text":"",
"type":0
}
},
{
"name":"二级测试",
"sub_button":[
{
"name":"测试",
"id":4247867901937687,
"type":"view",
"url":"http://www.worldyao.cn/WeChat"
},
{
"name":"测试",
"id":4247867902201619,
"type":"view",
"url":"http://www.worldyao.cn/WeChat"
}
],
"id":4247867902531119
}
]
}
}
请求的URL地址
https://m.api.weibo.com/2/messages/menu/create.json
HTTP请求方式
GET
https://m.api.weibo.com/2/messages/menu/show.json?access_token=ACCESS_TOKEN
返回结果
{
"menu":{
"button":[
{
"name":"获取菜单",
"type":"click",
"key":"getmenu"
},
{
"name":"测试二",
"type":"click",
"key":"jihji"
},
{
"name":"二级测试",
"sub_button":[
{
"name":"测试",
"type":"view",
"url":"http://www.worldyao.cn/WeChat"
},
{
"name":"测试",
"type":"view",
"url":"http://www.worldyao.cn/WeChat"
}
]
}
]
}
}
接口请求参数
参数名称
值的类型
是否必填
说明描述
access_token
string
true
在账号Profile页--> 管理中心 --> 粉丝服务--> 高级功能--> 开发模式中获取,详细参考 获取粉丝服务平台开发接口的access token。
