1.无后台管理的自定义菜单

①根据appId和appSecret获取acessToken

a.向服务器发送请求 httpRequst(url,method,outPutStr)  返回jsonObject(包含了access_token和expires_in字段值)getString(""),getInt("")

1)建立双向认证https请求(SSLContext.getInstance("SSL", "SunJSSE").init(KeyManager,TrustManager,SecureRandom).getSocketFactory())【https和ssl】

WechatUtil.java

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ConnectException;
import java.net.URL;import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;import net.sf.json.JSONException;
import net.sf.json.JSONObject;import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import com.kerui.domains.community.entity.Ticket;
import com.kerui.domains.model.AccessToken;
import com.kerui.domains.model.AccessTokenByCode;
import com.kerui.domains.model.Menu;
public class WechatUtil{
 private static Logger log = LoggerFactory.getLogger(WechatUtil.class);
/*** access_token是公众号的全局唯一票据,公众号调用各接口时都需使用access_token。正常情况下access_token有效期为7200秒,重复获取将导致上次获取的access_token失效。* 公众号可以使用AppID和AppSecret调用本接口来获取access_token。AppID和AppSecret可在开发模式中获得(需要已经成为开发者,且帐号没有异常状态)。* *///获取access_token的接口地址(GET) 限200(次/天)  public final static String access_token_url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";  // 菜单创建(POST) 限100(次/天)  public static String menu_create_url = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN";/* 使用接口创建自定义菜单后,开发者还可使用接口删除当前使用的自定义菜单* https://api.weixin.qq.com/cgi-bin/menu/delete?access_token=ACCESS_TOKEN*/public final static String delete_menulist="https://api.weixin.qq.com/cgi-bin/menu/delete?access_token=ACCESS_TOKEN";//公众号可通过本接口来获取帐号的关注者列表,关注者列表由一串OpenID(加密后的微信号,每个用户对每个公众号的OpenID是唯一的)组成。一次拉取调用最多拉取10000个关注者的OpenID,可以通过多次拉取的方式来满足需求。 public final static String getwechatuser="https://api.weixin.qq.com/cgi-bin/user/get?access_token=ACCESS_TOKEN ";//获取微信关注列表超过10000(count>10000)public final static String getmoreweichatuser="https://api.weixin.qq.com/cgi-bin/user/get?access_token=ACCESS_TOKEN&next_openid=NEXT_OPENID";//向微信关注用户发送信息;http请求方式:POSTpublic final static String postinfotouser="https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=ACCESS_TOKEN";
/*** 获取access_token* * @param appid*            凭证* @param appsecret*            密钥* @return*/public static AccessToken getAccessToken(String appid, String appsecret) {AccessToken accessToken = null;String requestUrl = access_token_url.replace("APPID", appid).replace("APPSECRET", appsecret);JSONObject jsonObject = httpRequest(requestUrl, "GET", null);// 如果请求成功if (null != jsonObject) {try {accessToken = new AccessToken();accessToken.setToken(jsonObject.getString("access_token"));accessToken.setExpiresIn(jsonObject.getInt("expires_in"));} catch (JSONException e) {accessToken = null;// 获取token失败log.error("获取token失败 errcode:{} errmsg:{}",jsonObject.getInt("errcode"),jsonObject.getString("errmsg"));}}return accessToken;}
 /*** 创建菜单* * @param menu*            菜单实例* @param accessToken*            有效的access_token* @return 0表示成功,其他值表示失败*/public static int createMenu(Menu menu, String accessToken) {int result = 0;// 拼装创建菜单的urlString url = menu_create_url.replace("ACCESS_TOKEN", accessToken);// 将菜单对象转换成json字符串String jsonMenu = JSONObject.fromObject(menu).toString();// 调用接口创建菜单JSONObject jsonObject = httpRequest(url, "POST", jsonMenu);if (null != jsonObject) {if (0 != jsonObject.getInt("errcode")) {result = jsonObject.getInt("errcode");log.error("创建菜单失败 errcode:{} errmsg:{}",jsonObject.getInt("errcode"),jsonObject.getString("errmsg"));}}return result;}
/*** 发起https请求并获取结果* * @param requestUrl*            请求地址* @param requestMethod*            请求方式(GET、POST)* @param outputStr*            提交的数据* @return JSONObject(通过JSONObject.get(key)的方式获取json对象的属性值)*/public static JSONObject httpRequest(String requestUrl,String requestMethod, String outputStr) {JSONObject jsonObject = null;StringBuffer buffer = new StringBuffer();try {// 创建SSLContext对象,并使用我们指定的信任管理器初始化TrustManager[] tm = { new MyX509TrustManager() };SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");sslContext.init(null, tm, new java.security.SecureRandom());// 从上述SSLContext对象中得到SSLSocketFactory对象SSLSocketFactory ssf = sslContext.getSocketFactory();URL url = new URL(requestUrl);HttpsURLConnection httpUrlConn = (HttpsURLConnection) url.openConnection();httpUrlConn.setSSLSocketFactory(ssf);httpUrlConn.setDoOutput(true);httpUrlConn.setDoInput(true);httpUrlConn.setUseCaches(false);// 设置请求方式(GET/POST)httpUrlConn.setRequestMethod(requestMethod);if ("GET".equalsIgnoreCase(requestMethod))httpUrlConn.connect();// 当有数据需要提交时if (null != outputStr) {OutputStream outputStream = httpUrlConn.getOutputStream();// 注意编码格式,防止中文乱码outputStream.write(outputStr.getBytes("UTF-8"));outputStream.close();}// 将返回的输入流转换成字符串InputStream inputStream = httpUrlConn.getInputStream();InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");BufferedReader bufferedReader = new BufferedReader(inputStreamReader);String str = null;while ((str = bufferedReader.readLine()) != null) {buffer.append(str);}bufferedReader.close();inputStreamReader.close();// 释放资源inputStream.close();inputStream = null;httpUrlConn.disconnect();jsonObject = JSONObject.fromObject(buffer.toString());} catch (ConnectException ce) {log.error("Weixin server connection timed out.");} catch (Exception e) {log.error("https request error:{}", e);}return jsonObject;}
}

MyX509TrustManager.java

/** * 证书信任管理器(用于https请求) * <br>* X509证书信任管理器类* <br>* 证书信任管理器类就是实现了接口X509TrustManager的类*/
public class MyX509TrustManager implements X509TrustManager {  /*** 该方法检查客户端的证书,若不信任该证书则抛出异常。<br>* 由于我们不需要对客户端进行认证,因此我们只需要执行默认的信任管理器的这个方法。<br>* JSSE中,默认的信任管理器类为TrustManager。* **/public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {  }  /*** 该方法检查服务器的证书,若不信任该证书同样抛出异常。<br>* 通过自己实现该方法,可以使之信任我们指定的任何证书。<br>* 在实现该方法时,也可以简单的不做任何处理,即一个空的函数体,由于不会抛出异常,它就会信任任何证书。* */public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {  }  /*** 返回受信任的X509证书数组。* */public X509Certificate[] getAcceptedIssuers() {  return null;  }
}

SearchMenuManager.java

 private static Logger log = LoggerFactory.getLogger(SearchMenuManager.class);/*** access_token是公众号的全局唯一票据,公众号调用各接口时都需使用access_token。正常情况下access_token有效期为7200秒,重复获取将导致上次获取的access_token失效。* 公众号可以使用AppID和AppSecret调用本接口来获取access_token。AppID和AppSecret可在开发模式中获得(需要已经成为开发者,且帐号没有异常状态)。* */public static void main(String[] args) {  //个人测试账号String appId = "xxxxxxxx";String appSecret = "xxxxxxxxx";           //根据appId和appSecret获取accessTokenAccessToken accessToken = WeixinUtil.<span style="color:#FF0000;">getAccessToken</span>(appId, appSecret);if(log.isInfoEnabled()){log.info("accessToken {}", accessToken.getToken());}//创建自定义菜单if(null != accessToken){int result = WeixinUtil.<span style="color:#FF0000;">createMenu</span>(<span style="color:#FF0000;">getMenu</span>(), accessToken.getToken());// 判断菜单创建结果  if (0 == result){log.info("菜单创建成功!"); }else{log.info("菜单创建失败,错误码:" + result);  }}}/*** 自定义菜单组建* @return 菜单Menu*/private static Menu getMenu() {ViewButton viewBtn1 = new ViewButton();viewBtn1.setName("tom");viewBtn1.setType("view");viewBtn1.setUrl(FileUtil.SERVER_PATH+"xlchen/tom");ViewButton viewBtn2 = new ViewButton();viewBtn2.setName("jerry");viewBtn2.setType("view");viewBtn2.setUrl(FileUtil.SERVER_PATH+"xlchen/jerry");
//
//          ViewButton viewBtn3 = new ViewButton();
//          viewBtn3.setName("刮刮乐");
//          viewBtn3.setType("view");
//          viewBtn3.setUrl("");CommonButton clickBtn1 = new CommonButton();clickBtn1.setName("大转盘");clickBtn1.setType("click");clickBtn1.setKey("1");CommonButton clickBtn2 = new CommonButton();clickBtn2.setName("砸金蛋");clickBtn2.setType("click");clickBtn2.setKey("2");//          CommonButton clickBtn3 = new CommonButton();
//          clickBtn3.setName("刮刮乐");
//          clickBtn3.setType("click");
//          clickBtn3.setKey("3");
//
//          ViewButton viewBtn4= new ViewButton();
//          viewBtn4.setName("查看中奖纪录");
//          viewBtn4.setType("view");
//          viewBtn4.setUrl("");
//
//          ViewButton viewBtn5 = new ViewButton();
//          viewBtn5.setName("关于我们");
//          viewBtn5.setType("view");
//          viewBtn5.setUrl("");
//
//          ViewButton viewBtn6 = new ViewButton();
//          viewBtn6.setName("投诉建议");
//          viewBtn6.setType("view");
//          viewBtn6.setUrl("");ComplexButton complexBtn = new ComplexButton();complexBtn.setName("顾客信息");complexBtn.setSub_button(new Button[]{viewBtn1,viewBtn2});ComplexButton complexBtn2 = new ComplexButton();complexBtn2.setName("活动介绍");complexBtn2.setSub_button(new Button[]{clickBtn1,clickBtn2});Menu menu = new Menu();menu.setButton(new Button[]{complexBtn,complexBtn2});return menu;}}

Button 为 以下 所有 Button 的父类。

ViewButton.java

   //view:跳转urlprivate String type;  private String url;private String name;  public String getName() {  return name;  }  public void setName(String name) {  this.name = name;  }  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;}  

CommonButton.java

//点击推事件:根据key值推送不同内容
private String type;
private String key;
private String name;  public String getName() {  return name;
}  public void setName(String name) {  this.name = name;
}  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;
}  

ComplexButton.java

    //组合菜单(一级菜单和二级菜单)private Button[] sub_button;  private String name;  public String getName() {  return name;  }  public void setName(String name) {  this.name = name;  }  public Button[] getSub_button() {  return sub_button;  }  public void setSub_button(Button[] sub_button) {  this.sub_button = sub_button;  }  

以上为代码部分,前提还需要 配置 公众账号的 JS 安全域名。

这里以个人测试账号为例,登录微信个人测试账号 微信公众平台个人测试登录。

登录完成之后,会看到对应的 appId 和 appsecret ,代码中需要使用到。下面有一栏叫做 JS接口安全域名

个人的话可以使用花生壳之类 映射一个域名,比如我这里填写的域名为:

194127e1f3.iok.la:21028

另外需要主要的是 上面代码中 的 ViewButton 在设置 url 的时候,该 url 也是有要求的,必须以 http 开头。

【wechat】微信开发——自定义菜单相关推荐

  1. 微信开发 -- 自定义菜单

    目前微信服务号自定义菜单最多包括3个一级菜单,每个一级菜单最多包含5个二级菜单.一级菜单最多4个汉字,二级菜单最多7个汉字,多出来的部分将会以"..."代替.请注意,创建自定义菜单 ...

  2. 微信开发自定义菜单获取OpenID

    OpenID: 每个微信用户对于每个公众号,有一个唯一的OpenID.对于其它公众号,OpenID是不同的 用途: 通过 OpenID,能访问到用户的基本信息 跟后台应用(比如商品销售)配合,可以管理 ...

  3. 微信开发--自定义菜单

    一.定义几个实体类 public class AccessToken {//这里定义一个AccessToken的实体类,用来保存获取到的accesstokenprivate String token; ...

  4. java自定义菜单跳转页面_微信公众号开发 自定义菜单跳转页面并获取用户信息实例详解...

    微信公众号开发 自定义菜单 请先读完本文再进行配置开发 请先前往微信平台开发者文档阅读"网页授权获取用户基本信息"的接口说明 在微信公众账号开发中,往往有定义一个菜单,然后用户点击 ...

  5. 微信公众号开发--自定义菜单跳转页面并获取用户信息(续)

    之前写过一篇微信公众号开发–自定义菜单跳转页面并获取用户信息 由于当时是刚学习微信公众号开发当时的思路虽然可行,不过不是最好的,最近也用到了需要获取用户信息的地方,再次整理一下. 流程 注意点 ### ...

  6. 公众号如何跳转到页面php,图文详解微信公众号开发自定义菜单跳转页面并获取用户信息实例...

    这篇文章主要介绍了微信公众号开发 自定义菜单跳转页面并获取用户信息实例详解的相关资料,需要的朋友可以参考下 微信公众号开发 自定义菜单 请先读完本文再进行配置开发 请先前往微信平台开发者文档阅读&qu ...

  7. 微信公众帐号开发-自定义菜单的创建及菜单事件响应的实例

    微信开发公众平台自定义菜单需要花钱认证才能实现,不想花钱只能玩测试账号了,不过这并不影响开发.我的开发都是基于柳峰老师的微信公众平台应用开发做的. 只要我们使用公众平台测试账号就可以开发自定义菜单了, ...

  8. 微信企业号开发:自定义菜单

    开发微信企业号可以通过程序自定义菜单,只需要调用相关的接口就可以实现. 其实这个菜单也就是微信底部的菜单,目前自定义菜单最多包括3个一级菜单,每个一级菜单最多包含5个二级菜单.一级菜单最多4个汉字,二 ...

  9. 微信公众号开发---自定义菜单的创建及菜单事件响应(java)

    微信5.0发布 2013年8月5日,伴随着微信5.0 iPhone版的发布,公众平台也进行了重要的更新,主要包括: 1)运营主体为组织,可选择成为服务号或者订阅号: 2)服务号可以申请自定义菜单: 3 ...

最新文章

  1. 【组队学习】【23期】Datawhale深度推荐模型
  2. iOS架构-cocoapods打包静态库(依赖私有库、开源库、私有库又包含静态库)(14)
  3. linux下jetty简单配置
  4. Oracle 原理: 公有同义词 和 私有同义词
  5. 第二十八章 springboot + zipkin(brave定制-AsyncHttpClient)
  6. Redis的诞生历程
  7. how is SAP UI5 configuration.js loaded in the runtime
  8. guns企业高级单体版(前后端不分离)运行启动
  9. css中margin:0 auto没作用
  10. 从“三只小猪”的故事到“高性能”测试自动化
  11. WordPress 实用SEO插件总结
  12. 传微软PK谷歌 将于2014年推出智能眼镜
  13. HCIE 面试 ----- OSPF
  14. 微信公众号创建与审核相关注意事项
  15. ssm启动不报错_ssm整合 启动表现层报错。。。
  16. 7大不跳槽就会死的理由!
  17. 趋势交易大师php,大道至简——多级别均线共振交易系统
  18. 云计算OpenStack环境搭建
  19. R语言:Windows字体数据库里没有这样的字体
  20. 静态网站以及动态网站

热门文章

  1. 拼多多给羊毛党发年终奖背后的那些事
  2. NGO招志愿者翻译,请分享
  3. 开关电源芯片(自学使用 码住)
  4. php实现ckeditor编辑器添加水印及使用误区
  5. 区块链技术系列(3)- Fabric基础架构原理
  6. ZZULIOJ:1053: 正弦函数
  7. 百度地图API Android SDK 常见问题
  8. 猫盘救砖方案(2021年最新版)
  9. http隧道、https、SSL层、http代理、在线代理、socks代理区别
  10. 什么是 Web 3.0?定义、功能和示例