博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【微信公众号开发】【3】自定义菜单
阅读量:2244 次
发布时间:2019-05-09

本文共 8767 字,大约阅读时间需要 29 分钟。

前言:

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;      }  }

 

转载于:https://www.cnblogs.com/huashengweilong/p/7700244.html

你可能感兴趣的文章
和机器学习和计算机视觉相关的数学
查看>>
十个值得一试的开源深度学习框架
查看>>
【LEETCODE】240-Search a 2D Matrix II
查看>>
【LEETCODE】53-Maximum Subarray
查看>>
【LEETCODE】215-Kth Largest Element in an Array
查看>>
【LEETCODE】312-Burst Balloons
查看>>
【LEETCODE】232-Implement Queue using Stacks
查看>>
【LEETCODE】225-Implement Stack using Queues
查看>>
【LEETCODE】155-Min Stack
查看>>
【LEETCODE】20-Valid Parentheses
查看>>
【LEETCODE】290-Word Pattern
查看>>
【LEETCODE】36-Valid Sudoku
查看>>
【LEETCODE】205-Isomorphic Strings
查看>>
【LEETCODE】204-Count Primes
查看>>
【LEETCODE】228-Summary Ranges
查看>>
【LEETCODE】27-Remove Element
查看>>
【LEETCODE】66-Plus One
查看>>
【LEETCODE】26-Remove Duplicates from Sorted Array
查看>>
【LEETCODE】118-Pascal's Triangle
查看>>
【LEETCODE】119-Pascal's Triangle II
查看>>