zoukankan      html  css  js  c++  java
  • 【微信公众号开发】【3】自定义菜单

    前言:

    1,目前公众号类型分为两种:服务号和订阅号(服务号主要面向企业、政府和其他组织,而订阅号主要面向媒体和个人)

    区别:只有服务号可以申请自定义菜单;服务号每月只能群发四条消息,而订阅号每天能群发一条消息(规则可能会变化,请以官方文档为准)

    2,如果开发者想通过HTTP请求访问公众平台的接口,就必须要有访问凭证,也就是access_token(方法在第二章)

    3,菜单数量为3(一级)*5(二级);一级菜单最多4个汉字,二级菜单最多7个汉字;可以有表情符号(自定义菜单实测字数可以更多)

    4,菜单创建或变更后可能并不会立即在公众号上显示出来,最长可能要24小时。但取消关注后再关注可以立即看到新菜单

    5,发布菜单:我是发送消息到公众号,判定如果是“menu”(随便什么都可以)则触发更新菜单(消息的发送和接收第四章会讲到)

    6,我目前修改菜单,需要改动代码,重新发布后再触发更新菜单。其实比较麻烦,最好是在数据库存储,在后台管理。

    正文:

    1,对菜单结构的封装  最终提交的json格式菜单数据应该是由对象直接转换得到,而不是在程序代码中拼一大堆json数据

    以下都是基类:

    菜单项的基类(所有一级菜单、二级菜单都共有一个相同的属性,那就是name)

    public class Button {  
        private String name;  
      
        public String getName() {  
            return name;  
        }  
      
        public void setName(String name) {  
            this.name = name;  
        }  
    }  

    子菜单项的封装(有可能是二级菜单项,也有可能是不含二级菜单的一级菜单)

    //click类型
    public
    class CommonButton extends Button { private String type; private String key; public String getType() { return type; } public void setType(String type) { this.type = type; } public String getKey() { return key; } public void setKey(String key) { this.key = key; } }  
    //view类型
    public
    class ViewButton extends Button { private String type; private String url; public String getType() { return type; } public void setType(String type) { this.type = type; } public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } }

    父菜单项(包含有二级菜单项的一级菜单)

    public class ComplexButton extends Button {  
        private Button[] sub_button;  
      
        public Button[] getSub_button() {  
            return sub_button;  
        }  
      
        public void setSub_button(Button[] sub_button) {  
            this.sub_button = sub_button;  
        }  
    }  

    整个菜单对象的封装

    public class Menu {  
        private Button[] button;  
      
        public Button[] getButton() {  
            return button;  
        }  
      
        public void setButton(Button[] button) {  
            this.button = button;  
        }  
    }  

    2,生成菜单   主要介绍click和view,其他类型还没接触到

    public static String menuManager() {           
        String respContent = "";//返回到微信的消息
        String access_token = WeixinUtil.getAccessToken(Config.fileName, Config.appId(), Config.appSecret());// 调用接口获取access_token
    
        if (!StringUtils.isEmpty(access_token)) {  
            // 调用接口创建菜单  
            int result = WeixinUtil.createMenu(getMenu(), access_token);  
    
            // 判断菜单创建结果  
            if (0 == result){               
                respContent = "菜单创建成功!";
            }else{
                respContent = "菜单创建失败,错误码:" + result; 
            }  
        }  
        
        return respContent;
    } 
        //组装菜单数据   
        private static Menu getMenu() {  
            ViewButton btn11 = new ViewButton();
            btn11.setName("测试view类型");  
            btn11.setType("view");  
            btn11.setUrl("https://www.ceshi.com/");  
      
            CommonButton btn12 = new CommonButton();  
            btn12.setName("公交查询");  
            btn12.setType("click");  
            btn12.setKey("12");  
      
            CommonButton btn13 = new CommonButton();  
            btn13.setName("周边搜索");  
            btn13.setType("click");  
            btn13.setKey("13");  
      
            CommonButton btn14 = new CommonButton();  
            btn14.setName("历史上的今天");  
            btn14.setType("click");  
            btn14.setKey("14");  
      
            CommonButton btn21 = new CommonButton();  
            btn21.setName("歌曲点播");  
            btn21.setType("click");  
            btn21.setKey("21");  
      
            CommonButton btn22 = new CommonButton();  
            btn22.setName("经典游戏");  
            btn22.setType("click");  
            btn22.setKey("22");  
      
            CommonButton btn23 = new CommonButton();  
            btn23.setName("美女电台");  
            btn23.setType("click");  
            btn23.setKey("23");  
      
            CommonButton btn24 = new CommonButton();  
            btn24.setName("人脸识别");  
            btn24.setType("click");  
            btn24.setKey("24");  
      
            CommonButton btn25 = new CommonButton();  
            btn25.setName("聊天唠嗑");  
            btn25.setType("click");  
            btn25.setKey("25");  
      
            CommonButton btn31 = new CommonButton();  
            btn31.setName("Q友圈");  
            btn31.setType("click");  
            btn31.setKey("31");  
      
            CommonButton btn32 = new CommonButton();  
            btn32.setName("电影排行榜");  
            btn32.setType("click");  
            btn32.setKey("32");  
      
            CommonButton btn33 = new CommonButton();  
            btn33.setName("幽默笑话");  
            btn33.setType("click");  
            btn33.setKey("33");  
      
            ComplexButton mainBtn1 = new ComplexButton();  
            mainBtn1.setName("生活助手");  
            mainBtn1.setSub_button(new Button[] { btn11, btn12, btn13, btn14 });  
      
            ComplexButton mainBtn2 = new ComplexButton();  
            mainBtn2.setName("休闲驿站");  
            mainBtn2.setSub_button(new Button[] { btn21, btn22, btn23, btn24, btn25 });  
      
            ComplexButton mainBtn3 = new ComplexButton();  
            mainBtn3.setName("更多体验");  
            mainBtn3.setSub_button(new Button[] { btn31, btn32, btn33 });  
      
            /** 
             * 这个公众号目前的菜单结构,每个一级菜单都有二级菜单项 
             *  
             * 在某个一级菜单下没有二级菜单的情况,menu该如何定义呢?
             * 比如,第三个一级菜单项不是“更多体验”,而直接是“幽默笑话”,那么menu应该这样定义 
             * menu.setButton(new Button[] { mainBtn1, mainBtn2, btn33 }); 
             */  
            Menu menu = new Menu();  
            menu.setButton(new Button[] { mainBtn1, mainBtn2, mainBtn3 });  
      
            return menu;  
        }  
    }  
    public static int createMenu(Menu menu, String accessToken) 
    {
      int result = 0;   String url = menu_create_url.replace("ACCESS_TOKEN", accessToken); // 拼装创建菜单的url   String jsonMenu = JSONObject.fromObject(menu).toString(); // 将菜单对象转换成json字符串   JSONObject jsonObject = HttpRequest.httpRequest(url, "POST", jsonMenu); // 调用接口创建菜单   if (null != jsonObject) {     if (0 != jsonObject.getInt("errcode")) {       result = jsonObject.getInt("errcode");       logger.info("创建菜单失败 errcode:{}" + jsonObject.getInt("errcode") + "errmsg:{}" + jsonObject.getString("errmsg"));     }   }   return result; }

    其中的httpRequest方法

        public static JSONObject httpRequest(String requestUrl, String requestMethod, String outputStr) 
        {  
            JSONObject jsonObject = null;  
            StringBuffer buffer = new StringBuffer();  
            try {  
                // 创建SSLContext对象,并使用我们指定的信任管理器初始化  
                TrustManager[] tm = { new MyX509TrustManager() };  
                SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");  
                sslContext.init(null, tm, new java.security.SecureRandom());  
                // 从上述SSLContext对象中得到SSLSocketFactory对象  
                SSLSocketFactory ssf = sslContext.getSocketFactory();  
      
                URL url = new URL(requestUrl);  
                HttpsURLConnection httpUrlConn = (HttpsURLConnection) url.openConnection();  
                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 != outputStr) {  
                    OutputStream outputStream = httpUrlConn.getOutputStream();  
                    // 注意编码格式,防止中文乱码  
                    outputStream.write(outputStr.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();  
                
                logger.info("返回信息:"+ buffer.toString());
                jsonObject = JSONObject.fromObject(buffer.toString());  
            } catch (ConnectException ce) {  
                logger.info("Weixin server connection timed out.");  
            } catch (Exception e) {  
                logger.info("https request error:{}"+e);  
            }  
            return jsonObject;  
        }   
    //证书信任管理器(用于https请求)  
    public class MyX509TrustManager implements X509TrustManager 
    {    
        public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {  
        }  
      
        public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {  
        }  
      
        public X509Certificate[] getAcceptedIssuers() {  
            return null;  
        }  
    }
  • 相关阅读:
    介绍一些好用的ArcToolbox工具(默认ArcGIS没有)
    我的技术博客开始啦
    Qualcomm和MTK两个android平台比较
    kali安装nessus
    ImportError: cannot import name pxssh
    python 批量下载文件
    GitHub如何修改用户名
    Sass中使用@each循环
    PhpStorm 实用快捷键
    GitHub如何删除一个repository(仓库)
  • 原文地址:https://www.cnblogs.com/huashengweilong/p/7700244.html
Copyright © 2011-2022 走看看