Java开发微博粉丝服务(3)——自定义菜单的设定

xiaoxiao2021-02-28  42

第三部分——自定义菜单的设定

文档编写:董尧

日期:2018.6.5

一、自定义菜单创建接口

二、自定义菜单查询接口

一、自定义菜单创建接口

1、请求说明

请求的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后的字符串格式,具体内容格式详见注意事项。

2、菜单说明

官方实例:

{

    "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

(1)、sub_button的封装

在该个包下创建一个类,该个类的名称是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; } }
(2)、Button的封装

根据官方的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)、创建一个二级菜单
/** * 创建二级菜单,通过传递相对应的属性 */ public static Sub_Button createTwoMenu(String type,String name,String url,String key){ Sub_Button sub_button = new Sub_Button(); sub_button.setType(type); sub_button.setName(name); sub_button.setUrl(url); sub_button.setKey(key); return sub_button; }
(4)、创建一个一级菜单
/** * 创建一级菜单,通过传递相对应的参数进行设置相对应的菜单属性 */ public static Button createOneMenu(String type,String name,String key){ Button button = new Button(); button.setType(type); button.setName(name); button.setKey(key); return button; }

根据官方的开发文档,一级菜单最多有3个,二级菜单最多有5个,对此我们将一、二级菜单进行组合封装,

(5)、二级菜单数组的封装
/** * 以下5个方法是封装二级菜单,微博最多可以设置5个二级菜单 * @param sub_button * @return */ public static Sub_Button[] packageTwoMenu(Sub_Button sub_button){ Sub_Button[] sub_group = {sub_button}; return sub_group; } public static Sub_Button[] packageTwoMenu(Sub_Button sub_button1,Sub_Button sub_button2){ Sub_Button[] sub_group = {sub_button1,sub_button2}; return sub_group; } public static Sub_Button[] packageTwoMenu(Sub_Button sub_button1,Sub_Button sub_button2,Sub_Button sub_button3){ Sub_Button[] sub_group = {sub_button1,sub_button2,sub_button3}; return sub_group; } public static Sub_Button[] packageTwoMenu(Sub_Button sub_button1,Sub_Button sub_button2,Sub_Button sub_button3,Sub_Button sub_button4){ Sub_Button[] sub_group = {sub_button1,sub_button2,sub_button3,sub_button4}; return sub_group; } public static Sub_Button[] packageTwoMenu(Sub_Button sub_button1,Sub_Button sub_button2,Sub_Button sub_button3,Sub_Button sub_button4,Sub_Button sub_button5){ Sub_Button[] sub_group = {sub_button1,sub_button2,sub_button3,sub_button4,sub_button5}; return sub_group; }
(6)、一级菜单数组的封装
/** * 以下三个方法是一级菜单的封装 * @param button * @return */ public static Button[] packageOneMenu(Button button){ Button[] bt_group = {button}; return bt_group; } public static Button[] packageOneMenu(Button button1,Button button2){ Button[] bt_group = {button1,button2}; return bt_group; } public static Button[] packageOneMenu(Button button1,Button button2,Button button3){ Button[] bt_group = {button1,button2,button3}; return bt_group; }
(7)菜单的组合

这里我用了两种方式

第一种:将一级菜单单独组合
/** * 创建一级菜单,但是这个方法是一级菜单下含有二级菜单的方法 * @param name * @param sub_button * @return */ public static Button createOneMenu(String name,Sub_Button[] sub_button){ Button bt_sb = new Button(); bt_sb.setName(name); bt_sb.setSub_button(sub_button); return bt_sb; } /** * 以下三个方法是一级菜单的封装 * @param button * @return */ public static Button[] packageOneMenu(Button button){ Button[] bt_group = {button}; return bt_group; } public static Button[] packageOneMenu(Button button1,Button button2){ Button[] bt_group = {button1,button2}; return bt_group; } public static Button[] packageOneMenu(Button button1,Button button2,Button button3){ Button[] bt_group = {button1,button2,button3}; return bt_group; }
第二种:全部组合

/** * 创建一级菜单,但是这个方法是一级菜单下含有二级菜单的方法 * @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

            }

        ]

    }

}

二、自定义菜单查询接口

1、请求说明

请求的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。

 

第四部分——整个框架

转载请注明原文地址: https://www.6miu.com/read-2623266.html

最新回复(0)