微信开发手册(9)

2025-12-14 00:50:30

1、凭证access_token的获取方法

继续在先前通用请求方法的类WeixinUtil.java中加入以下代码,用于获取接口访问凭证:

自定义菜单的创建方法

继续在先前通用请求方法的类WeixinUtil.java中加入以下代码,用于创建自定义菜单:

package edu.siso.util;

import java.io.BufferedReader;

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 org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import net.sf.json.JSONException;

import net.sf.json.JSONObject;

import edu.siso.pojo.AccessToken;

import edu.siso.pojo.Menu;

public class WeixinUtil {

private static Logger log = LoggerFactory.getLogger(WeixinUtil.class);

// 获取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";  

 

/** 

* 获取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;  

}  

  /** 

     * 发起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;  

   }  

// 菜单创建(POST) 限100(次/天)  

public static String menu_create_url = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN";  

  

/** 

 * 创建菜单 

 *  

 * @param menu 菜单实例 

 * @param accessToken 有效的access_token 

 * @return 0表示成功,其他值表示失败 

 */  

public static int createMenu(Menu menu, String accessToken) {  

    int result = 0;  

  

    // 拼装创建菜单的url  

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

}  

}

2、调用封装的方法创建自定义菜单:

package edu.siso.main;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import edu.siso.pojo.AccessToken;

import edu.siso.pojo.Button;

import edu.siso.pojo.CommonButton;

import edu.siso.pojo.ComplexButton;

import edu.siso.pojo.Menu;

import edu.siso.pojo.ViewButton;

import edu.siso.util.WeixinUtil;

public class MenuManager {

private static Logger log = LoggerFactory.getLogger(MenuManager.class);

public static void main(String[] args) {

// 第三方用户唯一凭证  

        String appId = "wx8bf27c4ee65c50b5";  

        // 第三方用户唯一凭证密钥  

        String appSecret = "afa43e6065940d9b797ac497d0cbab67";  

  

        // 调用接口获取access_token  

        AccessToken at = WeixinUtil.getAccessToken(appId, appSecret);  

  

        if (null != at) {  

            // 调用接口创建菜单  

            int result = WeixinUtil.createMenu(getMenu(), at.getToken());  

  

            // 判断菜单创建结果  

            if (0 == result)  

                log.info("菜单创建成功!");  

            else  

                log.info("菜单创建失败,错误码:" + result);  

        }  

}

/** 

     * 组装菜单数据 

     *  

     * @return 

     */  

    private static Menu getMenu() {  

        CommonButton btn11 = new CommonButton();  

        btn11.setName("百度(click事件)");  

        btn11.setType("click");  

        btn11.setKey("11");  

  

        

        

        CommonButton btn12 = new CommonButton();  

        btn12.setName("公交查询");  

        btn12.setType("click");  

        btn12.setKey("12");  

  

        CommonButton btn13 = new CommonButton();  

        btn13.setName("周边搜索");  

        btn13.setType("click");  

        btn13.setKey("13");  

  

        CommonButton btn14 = new CommonButton();  

        btn14.setName("历史上的今天");  

        btn14.setType("click");  

        btn14.setKey("14");  

  

        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 btn31 = new CommonButton();  

        btn31.setName("Q友圈");  

        btn31.setType("click");  

        btn31.setKey("31");  

  

        CommonButton btn32 = new CommonButton();  

        btn32.setName("电影排行榜");  

        btn32.setType("click");  

        btn32.setKey("32");  

  

        CommonButton btn33 = new CommonButton();  

        btn33.setName("幽默笑话");  

        btn33.setType("click");  

        btn33.setKey("33");  

        

        ViewButton btn15=new ViewButton();

        btn15.setName("百度(url跳转)");  

        btn15.setType("view");  

        btn15.setUrl("http://www.baidu.com/");

  

        ComplexButton mainBtn1 = new ComplexButton();  

        mainBtn1.setName("生活助手");  

        mainBtn1.setSub_button(new Button[] { btn11,btn15,  btn12, btn13, btn14});  

  

        ComplexButton mainBtn2 = new ComplexButton();  

        mainBtn2.setName("校园动态");  

        mainBtn2.setSub_button(new CommonButton[] { btn21, btn22 });  

  

        ComplexButton mainBtn3 = new ComplexButton();  

        mainBtn3.setName("更多体验");  

        mainBtn3.setSub_button(new CommonButton[] { btn31, btn32, btn33 });  

  

        /** 

         * 这是公众号xiaoqrobot目前的菜单结构,每个一级菜单都有二级菜单项<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、注意:在运行以上代码时,需要将appId和appSecret换成你自己公众号的。

微信开发手册(9)

4、图中所有Java文件的源代码都在文章中贴出并进行了说明,图中使用到的jar也是Java开发中通用的jar包,很容易在网上下载到。

工程中引入的jar包主要分为两类:

1)第一类是json开发工具包,用于Java对象和Json字符串之间的转换;json开发工具包一共有3个jar:ezmorph-1.0.6.jar,json-lib-2.2.3-jdk13.jar和morph-1.1.1.jar。

2)第二类是slf4j日志工具包,用于记录系统运行所产生的日志,日志可以输出到控制台或文件中。

整个工程中,唯一没有讲到的是src下的log4j.properties的配置,也把它贴出来,方便大家参考,这样才是一个完整的工程源码。log4j.properties文件的内容如下:

log4j.rootLogger=info,console,file  

  

log4j.appender.console=org.apache.log4j.ConsoleAppender  

log4j.appender.console.layout=org.apache.log4j.PatternLayout  

log4j.appender.console.layout.ConversionPattern=[%-5p] %m%n  

  

log4j.appender.file=org.apache.log4j.DailyRollingFileAppender  

log4j.appender.file.DatePattern='-'yyyy-MM-dd  

log4j.appender.file.File=./logs/weixinmpmenu.log  

log4j.appender.file.Append=true  

log4j.appender.file.layout=org.apache.log4j.PatternLayout  

5、如何响应菜单点击事

参考CoreService类,接收响应菜单点击事件.

声明:本网站引用、摘录或转载内容仅供网站访问者交流或参考,不代表本站立场,如存在版权或非法内容,请联系站长删除,联系邮箱:site.kefu@qq.com。
猜你喜欢