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

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

文档编写:董尧

日期: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=%7B%22button%22%3A+%5B%7B%22type%22%3A+%22click%22%2C%22name%22%3A+%22%E8%8E%B7%E5%8F%96%E4%BC%98%E6%83%A0%E5%88%B8%22%2C%22key%22%3A+%22get_groupon%22%7D%2C%7B%22type%22%3A+%22click%22%2C%22name%22%3A+%22%E6%9F%A5%E8%AF%A2%E5%AE%A2%E6%9C%8D%E7%94%B5%E8%AF%9D%22%2C%22key%22%3A+%22the_big_brother_need_your_phone%22%7D%2C%7B%22name%22%3A+%22%E8%8F%9C%E5%8D%95%22%2C%22sub_button%22%3A+%5B%7B%22type%22%3A+%22view%22%2C%22name%22%3A+%22%E7%BD%91%E4%B8%8A4S%E5%BA%97%22%2C%22url%22%3A+%22http%3A%2F%2Fapps.weibo.com%2F1838358847%2F8rYu1uHD%22%7D%2C%7B%22type%22%3A+%22view%22%2C%22name%22%3A+%22%E7%A0%8D%E4%BB%B7%E5%9B%A2%22%2C%22url%22%3A+%22http%3A%2F%2Fapps.weibo.com%2F1838358847%2F8s1i6v74%22%7D%2C%7B%22type%22%3A+%22click%22%2C%22name%22%3A+%22%E4%B9%88%E4%B9%88%E5%93%92%22%2C%22key%22%3A+%22memeda%22%7D%5D%7D%5D%7D'

返回结果

//成功返回:

{

    "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。

第四部分——整个框架


猜你喜欢

转载自blog.csdn.net/qq_38277570/article/details/80630444