前两天断了一更,至于为什么,你们懂的~~
OK,继续接着上面说,信息的接收和发送已经封装完毕,那么接下来就是自定义菜单了。打开开发者文档,文档上是这样限制和解释的。
目前自定义菜单最多包括3个一级菜单,每个一级菜单最多包含5个二级菜单。一级菜单最多4个汉字,二级菜单最多7个汉字,多出来的部分将会以“...”代替。请注意,创建自定义菜单后,由于微信客户端缓存,需要24小时微信客户端才会展现出来。建议测试时可以尝试取消关注公众账号后再次关注,则可以看到创建后的效果。
原先我做的时候自定义菜单只有两种类型,现在增加到了八种,不过也是一样的意思,理解这两种了,其他的都是小意思。
进入重点,文档告诉了我们接口地址:https://api.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN,请求方式是POST,注意,这里用的是https协议,参数给我们的例子也是json数据类型的,但是,这个access_token是个什么鬼,没办法,只有再往前看,果然,它是一个基础接口里面的东西,介绍和限制我这里就不多说了,大家去看看就好,往下看,发现接口给我们了,请求方式是GET,那么现在唯一的问题就是如何去模拟HTTPS协议发送POST或者GET请求,代码如下:
package com.tane.util;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import org.apache.log4j.Logger;
import com.tane.head.utils.MenuUtil;
import net.sf.json.JSONObject;
public class HttpsRequest {
/**
* 发送https请求
* @param requestUrl 请求地址
* @param requestMethod 请求方式
* @param message 提交的数据
* @return @tane
*/
public static JSONObject httpsRequest(String requestUrl,String requestMethod,String message){
JSONObject json=null;
try {
//创建SSLContext对象
TrustManager[] tm={new MyX509TrustManager()};
SSLContext ssl=SSLContext.getInstance("SSL", "SunJSSE");
ssl.init(null, tm, new java.security.SecureRandom());
//从ssl对象中得到SSLSocketFactory对象
SSLSocketFactory ssf=ssl.getSocketFactory();
URL urlGet = new URL(requestUrl);
HttpsURLConnection http = (HttpsURLConnection) urlGet
.openConnection();
http.setSSLSocketFactory(ssf);
http.setDoOutput(true);
http.setDoInput(true);
http.setUseCaches(false);
http.setRequestMethod(requestMethod); // 设置请求方式
System.setProperty("sun.net.client.defaultConnectTimeout", "30000");// 连接超时30秒
System.setProperty("sun.net.client.defaultReadTimeout", "30000"); // 读取超时30秒
if(message!=null){
OutputStream outputStream=http.getOutputStream();
outputStream.write(message.getBytes("UTF-8"));
outputStream.close();
}
//从输入流中读取返回内容
InputStream is = http.getInputStream();
InputStreamReader inputStreamReader=new InputStreamReader(is,"utf-8");
BufferedReader bufferedReader=new BufferedReader(inputStreamReader);
String str=null;
StringBuffer buffer=new StringBuffer();
while((str=bufferedReader.readLine())!=null){
buffer.append(str);
}
//释放资源
inputStreamReader.close();
bufferedReader.close();
is.close();
is=null;
http.disconnect();
json=JSONObject.fromObject(buffer.toString());
} catch (Exception e) {
e.printStackTrace();
}
return json;
}
}
自己定义的信任管理器:
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协议的请求方式,那么,根据上面的代码,我们稍微改一下,就可以得到HTTP协议的请求方式,如下:
public static JSONObject httpRequest(String requestUrl,String requestMethod,String message){
JSONObject json=null;
try {
URL url = new URL(requestUrl);
HttpURLConnection http = (HttpURLConnection) url.openConnection();
http.setDoOutput(false);
http.setDoInput(true);
http.setUseCaches(false);
http.setRequestMethod(requestMethod);
if(message!=null){
OutputStream outputStream=http.getOutputStream();
outputStream.write(message.getBytes("UTF-8"));
outputStream.close();
}
//从输入流中读取返回内容
InputStream is = http.getInputStream();
InputStreamReader inputStreamReader=new InputStreamReader(is,"utf-8");
BufferedReader bufferedReader=new BufferedReader(inputStreamReader);
String str=null;
StringBuffer buffer=new StringBuffer();
while((str=bufferedReader.readLine())!=null){
buffer.append(str);
}
//释放资源
inputStreamReader.close();
bufferedReader.close();
is.close();
is=null;
http.disconnect();
json=JSONObject.fromObject(buffer.toString());
} catch (Exception e) {
System.out.println(e.getStackTrace());
}
return json;
}
OK,util已经写好,那么接下来就是去调用了,先来获取access_token,URL地址告诉我们了,请求方式是GET,为了保险起见,我们还是先来测试一下:其中APPID和APPSECRET写自己的。
<span style="white-space:pre"> </span>@Test
public void getAccess_token(String appid,String appsecret){
String access_token="";
String access_tokenUrl="https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";
String requestUrl=access_tokenUrl.replace("APPID", appid).replace("APPSECRET", appsecret);
JSONObject json=httpsRequest(requestUrl,"GET",null);
if(json!=null){
try {
access_token=json.getString("access_token");
} catch (Exception e) {
access_token=null;
}
}
System.out.println(access_token);
}
得到access_token,接下来就是自定义菜单了,因为自定义菜单是POST请求方式,有提交的参数,而看到给我们的例子我们可知,参数类型是JSON数据类型,但如果真一个一个去拼接,就太麻烦了,而且还容易出错,所以事先我们先准备好
public class Button {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
package com.tane.bean;
public class ClickButton 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;
}
}
package com.tane.bean;
//包含子菜单的一级菜单
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;
}
}
想要几个,我们自己加就是了,然后我们用JSONObject.fromObject(menu).toString()去吧menu对象转成json类型的字符串就行了,方法如下:
/**
* 创建菜单
* @param menu 菜单实例
* @param access_token
* @return
*/
public static boolean createMenu(Menu menu,String access_token){
boolean result=false;
String requestUrl="https://api.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN";
requestUrl=requestUrl.replace("ACCESS_TOKEN", access_token);
//将菜单对象转换成json字符串
String jsonMenu=JSONObject.fromObject(menu).toString();
JSONObject json=HttpsRequest.httpsRequest(requestUrl, "POST", jsonMenu);
if(json!=null){
int errCode=json.getInt("errcode");
if(errCode==0){
result=true;
logger.debug("创建菜单成功");
}else{
result=false;
logger.debug("创建菜单失败"+errCode);
}
}
return result;
}
创建完毕,是不会给什么提示的,唯一判断方法是看返回码,如果返回码是0,则说明创建成功,当然,官方还给出了查询自定义菜单的接口,我们调用那个接口也能查出来,接口是https://api.weixin.qq.com/cgi-bin/menu/get?access_token=ACCESS_TOKEN,HTTPS协议,GET请求方式,剩下的事,都懂了,直接调用方法即可。