🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
##自定义菜单 ###简介 自定义菜单的开发,会让公众号更像是一个轻量级的应用。可以更好的提升公众号的交互属性。 ###自定义菜单创建 * * * * * ######**提示**: ######1.自定义菜单最多包括3个一级菜单,每个一级菜单最多5个二级菜单。 ######2.一级菜单最多4个汉字,二级菜单最多7个汉字,多出来的部分会以“...”代替。 ######3.创建自定义菜单后,菜单的刷新策略是,在用户进入公众号会话页或公众号profile页时,如果发现上一次拉取菜单的请求在5分钟以前,就会拉取一下菜单,如果菜单有更新,就会刷新客户端的菜单。测试时可以尝试取消关注公众账号后再次关注,则可以看到创建后的效果。 * * * * * * 自定义菜单接口有很多种类型(详细可参看开发者文档),这里只选择两个常用的接口进行说明(click和view) 1.click : 点击推事件 用户点击 click类型按钮后,微信服务器会通过消息接口推送消息类型为event的结构给开发者(微信消息接口后续会介绍)并且带上按钮中开发者填写的key值,开发者可以通过自定义的key值与用户进行交互; 2.view:跳转URL 用户点击view类型按钮后,微信客户端将会打开开发者在按钮中填写的网页URL,可与网页授权获取用户基本信息接口结合,获得用户基本信息。 **接口调用方式和请求示例“开发者文档”中有详细说明,这里仔细说下封装方法** ###封装菜单结构 通过官方API给出的 JSON格式,我们大概将菜单分为三类:click类型、view类型和混合型。每个菜单对象都有一个共同的 name属性(即菜单名称),因此需要定义一个菜单对象的基类,所有菜单对象都需要继承该类。代码如下 ~~~ /* * 菜单的基类 */ public class Button { private String name; public String getName(){ return name; } public void setName(String name){ this.name = name; } } ~~~ * click类型有type、name、key 3个属性,对应代码如下 ~~~ public class ClickButton extends Buttuon { 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(){ this.key = key; } } ~~~ * view 类型有type、name、url 3个属性 ~~~ public class ViewButton extends Buttuon { 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(){ this.url = url; } } ~~~ * 混合型的菜单按钮指的是含有自按钮的Button,也就是含有子菜单的一级菜单 ~~~ public class ComplexButton extends Button { private Button[] sub_button; public Buttuon[] getSub_button(){ return sub_button; } public void setSub_button(Button[] sub_button){ this.sub_button = sub_button; } } ~~~ * 最后是整个带单对象的封装,代码如下 ~~~ /** * 菜单封装 */ public class Meun { private Button[] button; public Button[] getButton(){ return button; } public void setButton(Button[] button){ this.button = button; } } ~~~ ### 创建菜单 我们通过以上封装类定义菜单的结构,得到JSON格式的菜单数据,代码如下 ~~~ public static void main(String[] args){ ClickButton btn1 = new ClickButton(); btn1.setName("第一个菜单"); btn1.setType("click"); btn1.setKey("m_1"); ViewButton btn2 = new ViewButton(); btn2.setName("第二个菜单"); btn2.setType("view"); btn2.setUrl("http://www.baidu.com"); ClickButton btn31 = new ClickButton(); btn31.setName("复合菜单1"); btn31.setType("click"); btn31.setKey("m_3_1"); ClickButton btn32 = new ClickButton(); btn32.setName("复合菜单2"); btn32.setType("click"); btn32.setKey("m_3_2"); //复合菜单包含两个click类型的菜单 ComplexButton btn3 = new ComplexButton(); btn3.setName("第三个菜单"); btn3.setSub_button(new Button[] {btn31,btn32}); //创建菜单对象 Menu menu = new Menu(); menu.setButton(new Button[] {btn1,btn2,btn3}); //将菜单对象转换成 JSON字符串 String jsonMenu = JSONObject.fromObject(menu).toString(); system.out.println(jsonMenu); } ~~~ 在得到JSON格式的菜单结构之后,我们需要发起HTTPS POST请求将菜单结构提交到https://api.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN 来创建菜单。代码如下 ~~~ // 菜单创建接口 String menuCreateUrl = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN"; //建立连接 URL url = new URL(menuCreateUrl); HttpsURLConnection httpUrlConn = (HttpsURLConnection) url.openConnection; //使用自定义的信任管理器 TrustManager[] tm = {new MyX509TTrustManager()}; SSLContext sslContext = SSLContext.getInstance("SSL","SunJSSE"); sslContext.init(null,tm,new java.security.SecureRandom()); SSLSocketFactory ssf = sslContext.getSocketFactory(); conn.setSSLSocketFactory(ssf); httpUrlConn.setDoOutput(true); httpUrlConn.setDoInput(true); //设置请求方式 httpUrlConn.setRequestMethod("POST"); //向输出流写菜单结构 OutputStream outputStream = httpUrlConn.getOutputStream(); outputStream.write(jsonMenu.getBytes("UTF-8")); outputStream.close(); //取得输入流 InputStream inputStream = httpUrlConn.getInputStream(); inputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8"); BufferedReader bufferedReader = new BufferedReader(inputStreamReader); //读取相应内容 StringBuffer buffer = new StringBuffer(); String str = null while ((str = bufferedReader.readLine()) != null){ buffer.append(str); } //关闭、释放资源 bufferedReader.close(); inputStreamReader.close(); inputStream.close(); httpUrlConn.disconnect(); //输出菜单创建结果 System.out.println(buffer); ~~~ 自定义菜单创建完成后,由于微信客户端的缓存问题,菜单不会马上显示,测试的时候,可以通过取消关后再次关注的方式来查看最新的菜单效果。 * * * * * ######**提示**:如果要修改公众账号的菜单,那么不需删除原有菜单,再次创建菜单会自动覆盖原有菜单。 * * * * * ###菜单删除和查询 * 查询接口 ~~~ https://api.weixin.qq.com/cgi-bin/menu/get?access_token=ACCESS_TOKEN ~~~ 查询接口返回的是json数组,注意点只有一个,menu为默认菜单,conditionalmenu为个性化菜单(详细demo可查看开发文档) * 删除接口 ~~~ https://api.weixin.qq.com/cgi-bin/menu/delete?access_token=ACCESS_TOKEN ~~~ **上述两个接口的调用方式和获取凭证接口一样,都是发送HTTPS GET请求调用,这里就不重复说明了** ###click菜单点击事件 菜单创建完成后,view类型的菜单会根据URL自动使用微信浏览器进行访问,而click类型菜单则需要我们自己开发响应事件。当点击click类型菜单时,微信服务器会向后台推送一条消息类型为event,事件类型为click的事件消息。而我们要做的就是接受该事件消息并作出响应,代码如下 ~~~ //判断消息类型 if(msgType.equals("event")){ //事件类型 String eventType = requestMap.get("Event"); //自定义菜单点击事件 if(eventType.equals("CLICK")){//特别注意,这里click要大写! //事件Key值,与创建菜单时的key值对应 String eventKey = requesMap.get("EventKey"); //根据key值判断用户点击的按钮 if(eventKey.equals("m_1")){ respContent = "点击了第一个菜单"; }esle if(eventKey.equals("m_3_1")){ respContent = "点击了复合菜单1"; }esle if(eventKey.equals("m_3_2")){ respContent = "点击了复合菜单2"; } } } ~~~ **详细处理方法,会在消息管理内说明**