1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > 微信公众号菜单栏开发 微信公众号接口开发个性化菜单 菜单事件开发

微信公众号菜单栏开发 微信公众号接口开发个性化菜单 菜单事件开发

时间:2019-02-14 19:55:33

相关推荐

微信公众号菜单栏开发 微信公众号接口开发个性化菜单 菜单事件开发

10万+IT人都在关注,史上最全面的微信开发实战教程:包含公众号,小程序,微信支付等开发案例

欢迎关注笔者个人博客:/

首先,直接上图,看效果,如下,有三个根菜单,每个菜单上有不同类型的子菜单,点击子菜单可以实现用户和公众号实时交互

本案例技术栈:springboot,mysql,logback,mybatis

菜单创建请求接口:https://api./cgi-bin/menu/create?access_token=ACCESS_TOKEN

首先是菜单项(按钮)的基类,所有一级菜单、二级菜单都有一个相同的属性,那就是name。菜单项基类的封装代码如下:

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

接着是子菜单项的封装。这里对子菜单是这样定义的:底部根菜单的二级菜单。这类子菜单项一定会包含三个属性:type、name和key,封装的代码如下

public class CommandButton 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;}}

接着封装父菜单项。对父菜单项的定义:包含有二级菜单项的一级菜单。这类菜单项包含有二个属性:name和sub_button,而sub_button是一个子菜单项数组。父菜单项的封装代码如下:

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

最后是整个菜单对象的封装,菜单对象包含多个根菜单项(最多只能有3个),这些菜单项即可以是子菜单项(不含二级菜单的一级菜单),也可以是父菜单项(包含二级菜单的菜单项),如果能明白上面所讲的,再来看封装后的代码就很容易理解了:

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

最后再封装一个链接类型的菜单,根据此处的名字也很好理解,不再赘述

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 WeiXinMenuUtil {private staticStringmenu_create_url="https://api./cgi-bin/menu/create?access_token=ACCESS_TOKEN"; private static Logger log = LoggerFactory.getLogger(WeiXinMenuUtil.class);public static int createMenu(Menu menu, String accessToken) {int result = 0;// 拼接创建菜单的urlString url = menu_create_url.replace("ACCESS_TOKEN", accessToken);// 将菜单对象转换成json字符串String jsonMenu = JSON.toJSONString(menu);// 调用接口创建菜单JSONObject jsonObject = WeiXinUtil.httpPost(url, "POST", jsonMenu);if (null != jsonObject) {if (0 != (Integer)jsonObject.get("errcode")) {result = (Integer)jsonObject.get("errcode");log.error("创建菜单失败 errcode:{} errmsg:{}", jsonObject.get("errcode"), jsonObject.getString("errmsg"));}}return result;}public static Menu initMenu(){//1.创建菜单Menu menu = new Menu();// 主菜单1ComplexButton cb1 = new ComplexButton();cb1.setName("技术干货");// 主菜单2ComplexButton cb2 = new ComplexButton();cb2.setName("交流合作");// 主菜单3ComplexButton cb3 = new ComplexButton();cb3.setName("演示功能");// 主菜单1下面的子菜单1ViewButton cb01 = new ViewButton();cb01.setName("微服务教程连载");cb01.setType("view");cb01.setUrl("/guobinhui/article/category/8739270");// 主菜单1下面的子菜单2ViewButton cb02 = new ViewButton();cb02.setName("公众号开发教程");cb02.setType("view");cb02.setUrl("/guobinhui/article/category/8534361");ViewButton cb03 = new ViewButton();cb03.setName("小程序开发教程");cb03.setType("view");cb03.setUrl("/guobinhui/article/category/7763266");ViewButton cb04 = new ViewButton();cb04.setName("JavaEE基础");cb04.setType("view");cb04.setUrl("/guobinhui");ViewButton cb05 = new ViewButton();cb05.setName("笔者博客");cb05.setType("view");cb05.setUrl("/");cb1.setSub_button(new ViewButton[]{cb01,cb02,cb03,cb04,cb05});// 主菜单2下面的子菜单1CommandButton cb11 = new CommandButton();cb11.setType("click");cb11.setKey("联系我");cb11.setName("联系笔者");CommandButton cb12 = new CommandButton();cb12.setName("技术交流");cb12.setType("click");cb12.setKey("18629374628");cb2.setSub_button(new CommandButton[]{cb11,cb12});CommandButton cb21 = new CommandButton();cb21.setType("scancode_waitmsg");cb21.setKey("rselfmenu_0_0");cb21.setName("扫码带提示");CommandButton cb22 = new CommandButton();cb22.setType("pic_sysphoto");cb22.setKey("rselfmenu_1_0");cb22.setName("系统拍照发图");CommandButton cb23 = new CommandButton();cb23.setType("pic_photo_or_album");cb23.setKey("rselfmenu_1_1");cb23.setName("拍照或者相册发图");CommandButton cb24 = new CommandButton();cb24.setType("pic_weixin");cb24.setKey("rselfmenu_1_2");cb24.setName("微信相册发图");CommandButton cb25 = new CommandButton();cb25.setType("location_select");cb25.setKey("rselfmenu_2_0");cb25.setName("发送地理位置");cb3.setSub_button(new CommandButton[]{cb21, cb22,cb23, cb24,cb25});menu.setButton(new Button[] { cb1,cb2, cb3});return menu; }}

二、微信接口凭证access_token的获取以及缓存实现

access_token可以用各种缓存插件或者线程,定时任务,写入数据库等多种方式对access_token进行缓存7200秒,开发者可以依据自己的喜好选择其一,本案例策略采用IO流定时写入文件的方法缓存。首先获取access_token:

public static JSONObject getToken()throws IOException{private String GET_ACCESS_TOKEN= "https://api./cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";String url = GET_ACCESS_TOKEN.replace("APPID",WeixinConstant.APPID).replace("APPSECRET",WeixinConstant.APPSECRET);JSONObject tokenObj = HttpGet(url);return tokenObj;}

接着缓存access_token,也就是每隔7200秒生成一次access_token,生成的缓存7200秒,这样其余用到access_token的从文件中读取的就是最新的,不会过期。

public static Map <String,Object> cacheToken() throws IOException {Gson gson = new Gson();Map <String,Object> map = new HashMap <String,Object> ();String token = null;JSONObject tokenObj = null; //需要获取的access_token对象;String filePath = System.getProperty("user.dir")+"/src/main/resources/static/token.txt";File file = new File(filePath);//Access_token保存的位置if (!file.exists())file.createNewFile();// 如果文件大小等于0,说明第一次使用,存入Access_tokenif (file.length() == 0) {tokenObj = WeiXinUtil.getToken();token = (String)tokenObj.get("access_token");FileOutputStream fos = new FileOutputStream(filePath, false);// 不允许追加tokenObj.put("expires_in",System.currentTimeMillis()/1000+"");String json = gson.toJson(tokenObj);fos.write(json.getBytes());fos.close();}else {//读取文件内容@SuppressWarnings("resource")FileInputStream fis = new FileInputStream(file);byte[] b = new byte[2048];int len = fis.read(b);String jsonAccess_token = new String(b, 0, len);// 读取到的文件内容JSONObject access_token = gson.fromJson(jsonAccess_token,JSONObject.class);if (access_token.get("expires_in") != null) {String lastSaveTime = (String)access_token.get("expires_in");long nowTime = System.currentTimeMillis()/1000;long remianTime = nowTime - Long.valueOf(lastSaveTime);if (remianTime < WeixinConstant.EXPIRESIN_TIME) {JSONObject access = gson.fromJson(jsonAccess_token,JSONObject.class);token = (String)access.get("access_token");} else {tokenObj = WeiXinUtil.getToken();FileOutputStream fos = new FileOutputStream(file, false);// 不允许追加tokenObj.put("expires_in",System.currentTimeMillis()/1000+"");String json = gson.toJson(tokenObj);fos.write((json).getBytes());fos.close();}}}map.put("access_token",token);return map;}

最后在项目的启动入口文件的main方法调用菜单创建方法进行初始化,那么项目在启动的时候,公众号的菜单就进行了初始化,用户就能看到公众号的菜单。

@SpringBootApplication@MapperScan(basePackages = "com.chenyun.cloud.dao")public class HelloServiceApplication {private final static Logger logger= LoggerFactory.getLogger(HelloServiceApplication.class);public static void main(String[] args) {SpringApplication.run(HelloServiceApplication.class, args);Map<String, Object> map;try {map = WeiXinUtil.cacheToken();String accessToken = (String)map.get("access_token");logger.info("accessToken:"+accessToken);Menu menu = WeiXinMenuUtil.initMenu();System.out.println(JSON.toJSONString(menu));int result = WeiXinMenuUtil.createMenu(menu,accessToken);if (0 == result){logger.info("菜单创建成功!");}else{logger.info("菜单创建失败,错误码:" + result);}} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}} }

启动项目后,打印的JSON格式的日志打就显示了创建的菜单结构。

下节内容为大家分享公众号菜单栏的各种点击事件开发案例,更多JavaEE资料请关注下面公众号,欢迎广大开发者朋友一起交流。更多微信公众号功能演示请扫码体验,笔者电话(微信):18629374628

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。