一、本节要点

1.菜单相关实体类的封装

参考官方文档中的请求包的内容,对菜单相关实体类进行封装。

这里需要格外注意的是,企业微信中请求包的数据是Json字符串格式的,而不是xml格式。关于json序列化的问题请参考上一节   Java企业微信开发_03_通讯录同步

2.创建菜单的接口

    public static String create_menu_url = "https://qyapi.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN&agentid=AGENTID"; 

注意此处的 ACCESS_TOKEN 与通讯录那里的 ACCESS_TOKEN 不同,记住只有通讯录 ACCESS_TOKEN 才会用到通讯录密钥。其他地方用的都是应用密钥。

还有虽然企业微信和微信公众号开发的接口不同,但是大体思路是相通的。

二、代码实现

1.实体类

按照企业微信官方文档中关于自定义菜单的请求包的说明,定义好实体类。

1.1 按钮的基类——Button

package com.ray.pojo.menu;  

/**
* @desc : 按钮的基类
*
* @author: shirayner
* @date : 2017-8-20 下午9:29:43
*/
public class Button {
private String name; public String getName() {
return name;
} public void setName(String name) {
this.name = name;
}
}

1.2 普通按钮(子按钮) ——CommonButton

package com.ray.pojo.menu;  

/**
* @desc : 普通按钮(子按钮)
*
* @author: shirayner
* @date : 2017-8-20 下午9:29:58
*/
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;
}
}

1.3 复杂按钮(父按钮) ——ComplexButton

package com.ray.pojo.menu;  

/**
* @desc : 复杂按钮(父按钮)
*
* @author: shirayner
* @date : 2017-8-20 下午9:30:17
*/
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;
}
}

1.4 view类型的菜单 ——ViewButton

package com.ray.pojo.menu;  

/**
* @desc : view类型的菜单
*
* @author: shirayner
* @date : 2017-8-20 下午9:30:44
*/
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;
}
}

1.5 菜单——Menu

package com.ray.pojo.menu;  

/**
* @desc : 菜单
*
* @author: shirayner
* @date : 2017-8-20 下午9:30:31
*/
public class Menu {
private Button[] button; public Button[] getButton() {
return button;
} public void setButton(Button[] button) {
this.button = button;
}
}

2.业务类

业务类主要是java对象序列化,获取accessToken以拼接请求ur,发送http请求调用接口。

2.1菜单业务类——MenuService

package com.ray.service;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import com.google.gson.Gson;
import com.ray.pojo.menu.Button;
import com.ray.pojo.menu.CommonButton;
import com.ray.pojo.menu.ComplexButton;
import com.ray.pojo.menu.Menu;
import com.ray.pojo.menu.ViewButton;
import com.ray.util.WeiXinUtil; import net.sf.json.JSONObject; public class MenuService {
private static Logger log = LoggerFactory.getLogger(MenuService.class);
// 菜单创建(POST) 限100(次/天)
public static String create_menu_url = "https://qyapi.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN&agentid=AGENTID"; /**
* 1.创建菜单
*
* @param menu 菜单实例
* @param accessToken 有效的access_token
* @return 0表示成功,其他值表示失败
*/
public void createMenu(String accessToken,Menu menu,int agentId) { //1.获取json字符串:将Menu对象转换为json字符串
Gson gson = new Gson();
String jsonMenu =gson.toJson(menu); //使用gson.toJson(user)即可将user对象顺序转成json
System.out.println("jsonMenu:"+jsonMenu); //2.获取请求的url
create_menu_url = create_menu_url.replace("ACCESS_TOKEN", accessToken)
.replace("AGENTID", String.valueOf(agentId)); //3.调用接口,发送请求,创建菜单
JSONObject jsonObject = WeiXinUtil.httpRequest(create_menu_url, "POST", jsonMenu);
System.out.println("jsonObject:"+jsonObject.toString()); //4.错误消息处理
if (null != jsonObject) {
if (0 != jsonObject.getInt("errcode")) {
log.error("创建菜单失败 errcode:{} errmsg:{}", jsonObject.getInt("errcode"), jsonObject.getString("errmsg"));
}
} } /**
* 2.组装菜单数据
*
* @return
*/
public Menu getMenu() {
ViewButton btn11 = new ViewButton();
btn11.setName("JSSDK测试");
btn11.setType("view");
btn11.setUrl("http://5hcn2d.natappfree.cc/WeiXin_SanFenBaiXue/index.jsp"); CommonButton btn12 = new CommonButton();
btn12.setName("使用帮助");
btn12.setType("click");
btn12.setKey("12"); CommonButton btn13 = new CommonButton();
btn13.setName("翻译功能");
btn13.setType("click");
btn13.setKey("13"); ViewButton btn14 = new ViewButton();
btn14.setName("上传图片");
btn14.setType("view");
btn14.setUrl("http://5hcn2d.natappfree.cc/WeiXin_SanFenBaiXue/uploadimg.jsp"); ViewButton btn15 = new ViewButton();
btn15.setName("上传图片2");
btn15.setType("view");
btn15.setUrl("http://5hcn2d.natappfree.cc/WeiXin_SanFenBaiXue/index2.jsp"); 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 btn33 = new CommonButton();
btn33.setName("幽默笑话");
btn33.setType("click");
btn33.setKey("33"); CommonButton btn34 = new CommonButton();
btn34.setName("用户反馈");
btn34.setType("click");
btn34.setKey("34"); CommonButton btn35 = new CommonButton();
btn35.setName("关于我们");
btn35.setType("click");
btn35.setKey("35"); ViewButton btn32 = new ViewButton();
btn32.setName("周边搜索");
btn32.setType("view");
btn32.setUrl("http://liufeng.gotoip2.com/xiaoqrobot/help.jsp"); ComplexButton mainBtn1 = new ComplexButton();
mainBtn1.setName("生活助手");
mainBtn1.setSub_button(new Button[] { btn11, btn12, btn13, btn14, btn15 }); 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, btn33, btn34, btn35, btn32 }); /**
* 这是企业号目前的菜单结构,每个一级菜单都有二级菜单项<br>
*
* 在某个一级菜单下没有二级菜单的情况,menu该如何定义呢?<br>
* 比如,第三个一级菜单项不是“更多体验”,而直接是“幽默笑话”,那么menu应该这样定义:<br>
* menu.setButton(new Button[] { mainBtn1, mainBtn2, btn33 });
*/
Menu menu = new Menu();
menu.setButton(new Button[] { mainBtn1, mainBtn2, mainBtn3 }); return menu;
} }

3.测试类

调用业务类,创建菜单

3.1菜单测试类——MenuTest

package com.ray.test;

import org.junit.Test;

import com.ray.pojo.menu.Menu;
import com.ray.service.MenuService;
import com.ray.util.WeiXinParamesUtil;
import com.ray.util.WeiXinUtil; public class MenuTest { @Test
public void testCreateMenu(){
//1.组装菜单
MenuService ms=new MenuService();
Menu menu=ms.getMenu(); //2.获取access_token:根据企业id和应用密钥获取access_token
String accessToken=WeiXinUtil.getAccessToken(WeiXinParamesUtil.corpId, WeiXinParamesUtil.agentSecret).getToken();
System.out.println("accessToken:"+accessToken); //3.创建菜单
ms.createMenu( accessToken, menu, WeiXinParamesUtil.agentId); } }

三、菜单事件的响应

菜单的事件响应,可归为 消息推送之被动回复消息 的一种(个人理解,望指正)。会在后续博客中补充。

四、参考资料

1.企业微信官方文档:https://work.weixin.qq.com/api/doc#10786

2.柳峰:[038] 微信公众帐号开发教程第14篇-自定义菜单的创建及菜单事件响应

Java企业微信开发_03_自定义菜单的更多相关文章

  1. Java企业微信开发_03_通讯录同步

    一.本节要点 1.获取通讯录密钥 获取方式: 登录企业微信—>管理工具—>通讯录同步助手—>开启“API接口同步”  ; 开启后,即可看到通讯录密钥,也可设置通讯录API的权限:读取 ...

  2. Java企业微信开发_05_消息推送之被动回复消息

    一.本节要点 1.消息的加解密 微信加解密包 下载地址:http://qydev.weixin.qq.com/java.zip      ,此包中封装好了AES加解密方法,直接调用方法即可. 其中,解 ...

  3. Java企业微信开发_09_身份验证之移动端网页授权(有完整项目源码)

    注: 源码已上传github: https://github.com/shirayner/WeiXin_QiYe_Demo 一.本节要点 1.1 授权回调域(可信域名) 在开始使用网页授权之前,需要先 ...

  4. Java企业微信开发_07_素材管理之上传本地临时素材文件

    一.本节要点 1.临时素材有效期 media_id是可复用的,同一个media_id可用于消息的多次发送(3天内有效) 2.上传文件时的http请求里都有啥 具体原理可参看: 为什么上传文件的表单需要 ...

  5. Java企业微信开发_05_消息推送之发送消息(主动)

    一.本节要点 1.发送消息与被动回复消息 (1)流程不同:发送消息是第三方服务器主动通知微信服务器向用户发消息.而被动回复消息是 用户发送消息之后,微信服务器将消息传递给 第三方服务器,第三方服务器接 ...

  6. Java企业微信开发_06_素材管理之上传本地临时素材文件至微信服务器

    一.本节要点 1.临时素材有效期 media_id是可复用的,同一个media_id可用于消息的多次发送(3天内有效) 2.上传文件时的http请求里都有啥 具体原理可参看: 为什么上传文件的表单需要 ...

  7. Java企业微信开发_04_消息推送之发送消息(主动)

    源码请见: Java企业微信开发_00_源码及资源汇总贴 一.本节要点 1.发送消息与被动回复消息 (1)流程不同:发送消息是第三方服务器主动通知微信服务器向用户发消息.而被动回复消息是 用户发送消息 ...

  8. Java企业微信开发_02_通讯录同步

    一.本节要点 1.获取通讯录密钥 获取方式: 登录企业微信—>管理工具—>通讯录同步助手—>开启“API接口同步”  ; 开启后,即可看到通讯录密钥,也可设置通讯录API的权限:读取 ...

  9. Java企业微信开发_01_接收消息服务器配置

    一.准备阶段 需要准备事项: 1.一个能在公网上访问的项目: 见:Java微信公众平台开发_01_本地服务器映射外网 2.一个企业微信账号: 去注册:(https://work.weixin.qq.c ...

随机推荐

  1. 【JMeter4.0学习(六)】之逻辑控制器说明

    主要demo例子在: 链接: https://pan.baidu.com/s/1OFdsrNG7PTOYQ8TdjiVtBQ 密码: tkd2 汇总参考文档:<Jmeter之逻辑控制器(Logi ...

  2. linux 给用户修改权限

    #添加一个用户 useradd xiaoming #设置密码 passwd xiaoming 回程 //设置密码就行了 #把用户修改成root权限 vi /etc/passwd #找到xiaoming ...

  3. TBSchedule源码阅读1-TBScheduleManagerFactory

    TBSchedule 1 TBScheduleManagerFactory 初始化    成员变量    ZKManager;    IScheduleDataManager;    Schedule ...

  4. centos7 修改sudoers文件

    使用root账户用 visudo 命令来修改. 转自: https://www.digitalocean.com/community/tutorials/how-to-edit-the-sudoers ...

  5. 利用freemarker生成带fusioncharts图片的word简报

    /**  * 利用freemarker生成带fusioncharts图片的word简报  *         烟台海颐软件技术论坛  *         作者  牟云飞 新建 *         毕业 ...

  6. 九度OJ 1350:二叉树的深度 (二叉树)

    时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:1044 解决:614 题目描述: 输入一棵二叉树,求该树的深度.从根结点到叶结点依次经过的结点(含根.叶结点)形成树的一条路径,最长路径的长 ...

  7. 【python】-- web开发之DOM

    DOM 文档对象模型(Document Object Model,DOM)是一种用于HTML和XML文档的编程接口.它给文档提供了一种结构化的表示方法,可以改变文档的内容和呈现方式.我们最为关心的是, ...

  8. 13.Django模版

    没什么好说的,看官方文档 https://docs.djangoproject.com/en/1.9/ref/templates/builtins/

  9. Computer Vision: Algorithms and ApplicationsのImage processing

    实在是太喜欢Richard Szeliski的这本书了.每一章节(after chapter3)都详述了该研究方向比較新的成果.还有很多很多的reference,假设你感兴趣.全然能够看那些參考论文 ...

  10. 解决oracle锁表

    1.查看被锁住的表select b.owner,b.object_name,a.session_id,a.locked_mode from v$locked_object a,dba_objects ...