06 - 微信公众号的菜单配置
目录
1.微信公众号菜单
首先要配置微信公众号的菜单之前,需要了解微信平台对菜单的api是如何进行定义的。
详细信息参考url如下:
https://developers.weixin.qq.com/doc/offiaccount/Custom_Menus/Creating_Custom-Defined_Menu.html
调用的微信请求如下:
https://api.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN
其中参数access_token 我们已经在05节中获取到了,我们就用没有超时的access_token去进行请求调用
click和view的请求示例(其他的类型请参考官方文档)
{
"button": [
{
"key": "1",
"name": "一级菜单1",
"type": "click"
},
{
"name": "一级菜单2",
"type": "view",
"url": "http://www.baidu.com"
},
{
"name": "菜单",
"sub_button": [
{
"name": "二级菜单",
"type": "view",
"url": "http://fanyi.youdao.com/"
}
]
}
]
}
在创建目录请求的可以分为2个部分
- 抽象报文信息(报文信息的对象化)
- 发送请求,修改公众号的目录结构
1.1.抽象报文信息
在抽象报文信息之前,我们需要对报文进行分析
首先不管是type类型是click还是view,都有name名称,那么我们可以把这个公共的抽取出来。
//这里讲下我为什么把这个类设置成抽象类
//当节点1(一级菜单1)和节点2(一级菜单2)是两种不同的类型。
//但是呢button中需要有两种不同的类型,所以就做了抽象类进行处理
public abstract class AbstractMenu {
// 抽取出来的公共参数
public String name;
// get set方法省略
}
然后我们可以按照从内到外的情况逐个进行抽象。
- 首先我们先创建最底层的基本对象分别是Type为view、click的对象(如果设置不同的类型请参考微信公众号的详细文档)
// 由于是测试 所以方法的命名是不符合规范的
public class ClickButten extends AbstractMenu {
private String type= "click";
private String key;
// 省略get set方法
public ClickButten(String name,String key) {
super(name);
this.key = key;
}
}
public class ViewButten extends AbstractMenu {
private String type = "view";
private String url;
// 省略get set方法
public ViewButten(String name,String url) {
super(name);
this.url = url;
}
}
- 然后我们在创建子菜单对象
public class SubButten extends AbstractMenu {
List<AbstractMenu> sub_button = new ArrayList<AbstractMenu>();
// 省略 get set方法
public SubButten(String name) {
super(name);
}
}
- 创建完成子菜单之后就是创建最大的菜单
public class Button {
List<AbstractMenu> button = new ArrayList<AbstractMenu>();
// 省略 get set方法
}
- 最后进行验证的流程
@Test
void TestMenu(){
Button button = new Button();
button.getButton().add(new ClickButten("一级菜单1","1"));
button.getButton().add(new ViewButten("一级菜单2","http://www.baidu.com"));
SubButten subButten = new SubButten("菜单");
subButten.getSub_button().add(new ViewButten("二级菜单","http://fanyi.youdao.com/"));
button.getButton().add(subButten);
//这块被坑了 使用的api是 net.sf.json.JSONObject 我一直以为使用的是org.json(原生的json包)
JSONObject jsonObject = JSONObject.fromObject(button);
System.out.println(jsonObject.toString());
}
使用postman调用修改,效果图如下所示。
1.2.菜单配置
能够组装请求报文,之后就是调用发送求情。
void Testpost() throws Exception {
// 菜单的url进行拼接
Button button = new Button();
button.getButton().add(new ClickButten("一级菜单1","1"));
button.getButton().add(new ViewButten("一级菜单2","http://www.baidu.com"));
SubButten subButten = new SubButten("菜单");
subButten.getSub_button().add(new ViewButten("二级菜单","http://fanyi.youdao.com/"));
button.getButton().add(subButten);
//这块被坑了 使用的api是 net.sf.json.JSONObject 我一直以为使用的是org.json(原生的json包)
JSONObject jsonObject = JSONObject.fromObject(button);
String ACCESS_TOKEN ="42_lh4kVHJDHUTQtHfUxrjGqGfKTJKcpqO7jxGmhIwdncmOb9NH8YJ_GhNTDDxzMb1EBGqm
SckUqs7mL6ozYr-f1JNnc3J7PmaGbnbXDl0BL6oBf9OMyGY3yensACdpnoF1zoMf2QxZArQUbVXOKYPbAEARFW";
URL url = new URL(MENU_URL.replace("ACCESS_TOKEN",ACCESS_TOKEN));
URLConnection urlConnection = url.openConnection();
//设置为可以发送数据的状态
urlConnection.setDoOutput(true);
//获取输出流
OutputStream outputStream = urlConnection.getOutputStream();
// 这个地方要特别的注意,在发送给微信中含有中文的时候编码需要设置成utf-8否则会报错
outputStream.write(jsonObject.toString().getBytes("utf-8"));
outputStream.close();
InputStream is = urlConnection.getInputStream();
byte [] b = new byte[1024];
int len;
StringBuilder sb = new StringBuilder();
while((len=is.read(b))!= -1){
sb.append(new String(b,0,len));
}
System.out.println(sb.toString());
}
注:在配置完菜单之后,每次用户点击菜单,就会给后台服务器发送消息。
下图就是我点击按钮时间传送到后台的消息,我们需要根据返回的信息MsgType以及EventKey对其进行处理。
{CreateTime=1614671191, EventKey=1, Event=CLICK, ToUserName=gh_7c94dc7e2130, FromUserName=orxnH5wNRLvz2DfNTopTGcL4y9ic, MsgType=event}
注:发送过来的信息是我解析过的,实际发送过来的数据是xml格式的