国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

java版微信公眾號(hào)開(kāi)發(fā)(四):自定義菜單的實(shí)現(xiàn)

mo0n1andin / 1430人閱讀

摘要:想要實(shí)現(xiàn)自定義菜單的功能,需要有已認(rèn)證訂閱號(hào)和已認(rèn)證服務(wù)號(hào)。測(cè)試時(shí)可以嘗試取消關(guān)注公眾賬號(hào)后再次關(guān)注,則可以看到創(chuàng)建后的效果。

想要實(shí)現(xiàn)自定義菜單的功能,需要有已認(rèn)證訂閱號(hào)和已認(rèn)證服務(wù)號(hào)。對(duì)于測(cè)試開(kāi)發(fā)來(lái)說(shuō),可以直接申請(qǐng)一個(gè)測(cè)試賬號(hào):http://mp.weixin.qq.com/debug...

同樣需要token的驗(yàn)證,前期接口已經(jīng)定義好了,直接拿來(lái)就可以

根據(jù)開(kāi)發(fā)者文檔,自定義菜單注意:

1、自定義菜單最多包括3個(gè)一級(jí)菜單,每個(gè)一級(jí)菜單最多包含5個(gè)二級(jí)菜單。
2、一級(jí)菜單最多4個(gè)漢字,二級(jí)菜單最多7個(gè)漢字,多出來(lái)的部分將會(huì)以“...”代替。
3、創(chuàng)建自定義菜單后,菜單的刷新策略是,在用戶進(jìn)入公眾號(hào)會(huì)話頁(yè)或公眾號(hào)profile頁(yè)時(shí),如果發(fā)現(xiàn)上一次拉取菜單的請(qǐng)求在5分鐘以前,就會(huì)拉取一下菜單,如果菜單有更新,就會(huì)刷新客戶端的菜單。測(cè)試時(shí)可以嘗試取消關(guān)注公眾賬號(hào)后再次關(guān)注,則可以看到創(chuàng)建后的效果。

自定義菜單接口可實(shí)現(xiàn)多種類型按鈕,如下:

接口調(diào)用請(qǐng)求說(shuō)明

http請(qǐng)求方式:POST(請(qǐng)使用https協(xié)議) https://api.weixin.qq.com/cgi...

click和view的請(qǐng)求示例

 {
     "button":[
     {    
          "type":"click",
          "name":"今日歌曲",
          "key":"V1001_TODAY_MUSIC"
      },
      {
           "name":"菜單",
           "sub_button":[
           {    
               "type":"view",
               "name":"搜索",
               "url":"http://www.soso.com/"
            },
            {
                 "type":"miniprogram",
                 "name":"wxa",
                 "url":"http://mp.weixin.qq.com",
                 "appid":"wx286b93c14bbf93aa",
                 "pagepath":"pages/lunar/index"
             },
            {
               "type":"click",
               "name":"贊一下我們",
               "key":"V1001_GOOD"
            }]
       }]
 }

參數(shù)說(shuō)明:

返回結(jié)果
正確時(shí)的返回JSON數(shù)據(jù)包如下:

{"errcode":0,"errmsg":"ok"}

錯(cuò)誤時(shí)的返回JSON數(shù)據(jù)包如下(示例為無(wú)效菜單名長(zhǎng)度):

{"errcode":40018,"errmsg":"invalid button name size"}

以上均來(lái)自官方說(shuō)明文檔。


pom引入jar包:


        
            net.sf.ezmorph
            ezmorph
            1.0.6
        

        
        
            commons-beanutils
            commons-beanutils
            1.8.0
        

        
        
            commons-collections
            commons-collections
            3.2.1
        
        
        
            commons-lang
            commons-lang
            2.3
        
        
        
            commons-logging
            commons-logging
            1.1.1
        

        
            net.sf.json-lib
            json-lib
            2.4
            jdk15
        
        
        
            dom4j
            dom4j
            1.6.1
        

        
            com.thoughtworks.xstream
            xstream
            1.4.9
        

定義菜單實(shí)體類:

/**
 * 按鈕基類
 * @author zhoumin
 * @create 2018-07-11 15:22
 */
@Setter
@Getter
public class BasicButton {
    private String name;
    private String url;
}

/**
 * 普通按鈕
 *
 * @author zhoumin
 * @create 2018-07-12 9:56
 */
@Setter
@Getter
public class CommonButton extends BasicButton {
    private String type;

    private String key;
}


/**
 * 父按鈕
 * @author zhoumin
 * @create 2018-07-11 15:24
 */
@Setter
@Getter
public class ComplexButton extends BasicButton {
    private BasicButton[] sub_button;

}

/**
 * 菜單
 * @author zhoumin
 * @create 2018-07-11 15:22
 */
@Setter
@Getter
public class Menu {
    private BasicButton[] button;
}

/**
 * @author zhoumin
 * @create 2018-07-11 15:23
 */
@Setter
@Getter
public class ViewButton extends BasicButton {
    private String type;
    private String name;
    private String url;

}

/**
 * 憑證
 * @author zhoumin
 * @create 2018-07-11 15:22
 */
@Setter
@Getter
public class AccessToken {
    /**
     *  獲取到的憑證
     */
    private String accessToken;
    
    /**
     *  憑證有效時(shí)間,單位:秒
     */
    private int expiresIn;
}

定義工具類:

/**
 * 實(shí)現(xiàn)接口
 * @author zhoumin
 * @create 2018-07-12 10:01
 */
public class MyX509TrustManager implements X509TrustManager {
    // 檢查客戶端證書(shū)
    @Override
    public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {

    }

    // 檢查服務(wù)器端證書(shū)
    @Override
    public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {

    }

    // 返回受信任的X509證書(shū)數(shù)組
    @Override
    public X509Certificate[] getAcceptedIssuers() {
        return new X509Certificate[0];
    }
}


/**
 * @author zhoumin
 * @create 2018-07-12 10:04
 */
public class CommonWechatUtil {
    private static Logger log = LoggerFactory.getLogger(CommonWechatUtil.class);
    // 憑證獲取(GET)
    public final static String token_url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";
    /**
     * 發(fā)送https請(qǐng)求
     *
     * @param requestUrl 請(qǐng)求地址
     * @param requestMethod 請(qǐng)求方式(GET、POST)
     * @param outputStr 提交的數(shù)據(jù)
     * @return JSONObject(通過(guò)JSONObject.get(key)的方式獲取json對(duì)象的屬性值)
     */
    public static JSONObject httpsRequest(String requestUrl, String requestMethod, String outputStr) {
        JSONObject jsonObject = null;
        try {
            // 創(chuàng)建SSLContext對(duì)象,并使用我們指定的信任管理器初始化
            TrustManager[] tm = { new MyX509TrustManager() };
            SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
            sslContext.init(null, tm, new java.security.SecureRandom());
            // 從上述SSLContext對(duì)象中得到SSLSocketFactory對(duì)象
            SSLSocketFactory ssf = sslContext.getSocketFactory();
            URL url = new URL(requestUrl);
            HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
            conn.setSSLSocketFactory(ssf);
            conn.setDoOutput(true);
            conn.setDoInput(true);
            conn.setUseCaches(false);
            // 設(shè)置請(qǐng)求方式(GET/POST)
            conn.setRequestMethod(requestMethod);
            // 當(dāng)outputStr不為null時(shí)向輸出流寫(xiě)數(shù)據(jù)
            if (null != outputStr) {
                OutputStream outputStream = conn.getOutputStream();
                // 注意編碼格式
                outputStream.write(outputStr.getBytes("UTF-8"));
                outputStream.close();
            }
            // 從輸入流讀取返回內(nèi)容
            InputStream inputStream = conn.getInputStream();
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
            String str = null;
            StringBuffer buffer = new StringBuffer();
            while ((str = bufferedReader.readLine()) != null) {
                buffer.append(str);
            }
            // 釋放資源
            bufferedReader.close();
            inputStreamReader.close();
            inputStream.close();
            inputStream = null;
            conn.disconnect();
            jsonObject = JSONObject.fromObject(buffer.toString());
        } catch (ConnectException ce) {
            log.error("連接超時(shí):{}", ce);
        } catch (Exception e) {
            log.error("https請(qǐng)求異常:{}", e);
        }
        return jsonObject;
    }
    /**
     * 獲取接口訪問(wèn)憑證
     *
     * @param appid 憑證
     * @param appsecret 密鑰
     * @return
     */
    public static AccessToken getToken(String appid, String appsecret) {
        AccessToken token = null;
        String requestUrl = token_url.replace("APPID", appid).replace("APPSECRET", appsecret);
        // 發(fā)起GET請(qǐng)求獲取憑證
        JSONObject jsonObject = httpsRequest(requestUrl, "GET", null);
        if (null != jsonObject) {
            try {
                token = new AccessToken();
                token.setAccessToken(jsonObject.getString("access_token"));
                token.setExpiresIn(jsonObject.getInt("expires_in"));
            } catch (JSONException e) {
                token = null;
                // 獲取token失敗
                log.error("獲取token失敗 errcode:{} errmsg:{}", jsonObject.getInt("errcode"), jsonObject.getString("errmsg"));
            }
        }
        return token;
    }
    /**
     * URL編碼(utf-8)
     *
     * @param source
     * @return
     */
    public static String urlEncodeUTF8(String source) {
        String result = source;
        try {
            result = java.net.URLEncoder.encode(source, "utf-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return result;
    }
    /**
     * 根據(jù)內(nèi)容類型判斷文件擴(kuò)展名
     *
     * @param contentType 內(nèi)容類型
     * @return
     */
    public static String getFileExt(String contentType) {
        String fileExt = "";
        if ("image/jpeg".equals(contentType))
            fileExt = ".jpg";
        else if ("audio/mpeg".equals(contentType))
            fileExt = ".mp3";
        else if ("audio/amr".equals(contentType))
            fileExt = ".amr";
        else if ("video/mp4".equals(contentType))
            fileExt = ".mp4";
        else if ("video/mpeg4".equals(contentType))
            fileExt = ".mp4";
        return fileExt;
    }





    // 菜單創(chuàng)建(POST) 限100(次/天)
    public static String menu_create_url = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN";

    /**
     * 創(chuàng)建菜單
     *
     * @param menu 菜單實(shí)例
     * @param accessToken 有效的access_token
     * @return 0表示成功,其他值表示失敗
     */
    public static int createMenu(Menu menu, String accessToken) {
        int result = 0;

        // 拼裝創(chuàng)建菜單的url
        String url = menu_create_url.replace("ACCESS_TOKEN", accessToken);
        // 將菜單對(duì)象轉(zhuǎn)換成json字符串
        String jsonMenu = JSONObject.fromObject(menu).toString();
        // 調(diào)用接口創(chuàng)建菜單
        JSONObject jsonObject = httpsRequest(url, "POST", jsonMenu);

        if (null != jsonObject) {
            if (0 != jsonObject.getInt("errcode")) {
                result = jsonObject.getInt("errcode");
                log.error("創(chuàng)建菜單失敗 errcode:{} errmsg:{}", jsonObject.getInt("errcode"), jsonObject.getString("errmsg"));
            }
        }

        return result;
    }

    public static String menu_get_url = "https://api.weixin.qq.com/cgi-bin/menu/get?access_token=ACCESS_TOKEN";
    /**
     * 查詢菜單
     *
     * @param accessToken 有效的access_token
     * @return 0表示成功,其他值表示失敗
     */
    public static JSONObject getMenu(String accessToken) {
        int result = 0;

        // 拼裝創(chuàng)建菜單的url
        String url = menu_get_url.replace("ACCESS_TOKEN", accessToken);
        // 將菜單對(duì)象轉(zhuǎn)換成json字符串
//        String jsonMenu = JSONObject.fromObject(menu).toString();
        // 調(diào)用接口創(chuàng)建菜單
        JSONObject jsonObject = httpsRequest(url, "POST", null);

        return jsonObject;
    }

    public static String menu_delete_url = "https://api.weixin.qq.com/cgi-bin/menu/delete?access_token=ACCESS_TOKEN";
    /**
     * 查詢菜單
     *
     * @param accessToken 有效的access_token
     * @return 0表示成功,其他值表示失敗
     */
    public static int deleteMenu(String accessToken) {
        int result = 0;

        // 拼裝創(chuàng)建菜單的url
        String url = menu_delete_url.replace("ACCESS_TOKEN", accessToken);
        // 調(diào)用接口創(chuàng)建菜單
        JSONObject jsonObject = httpsRequest(url, "POST", null);

        if (null != jsonObject) {
            if (0 != jsonObject.getInt("errcode")) {
                result = jsonObject.getInt("errcode");
                log.error("刪除菜單失敗 errcode:{} errmsg:{}", jsonObject.getInt("errcode"), jsonObject.getString("errmsg"));
            }
        }
        return result;
    }

定義常量:

/**
 * 添加id和密碼信息
 * @author zhoumin
 * @create 2018-07-11 17:07
 */
public class ConstantWeChat {
    public static final String APPID = "自己的AppId";

    public static final String APPSECRET = "自己的APPSecret";
}

實(shí)現(xiàn)方法:

/**
 * @author zhoumin
 * @create 2018-07-11 15:39
 */
public interface MenuService {
}


/**
 * @author zhoumin
 * @create 2018-07-11 15:40
 */
@Service("menuService")
public class MenuServiceImpl implements MenuService {
    private static final Logger LOGGER = LoggerFactory.getLogger(MenuServiceImpl.class);

    //    @Override
    public static Boolean createMenu() {
        // 第三方用戶唯一憑證
        String appId = ConstantWeChat.APPID;
        // 第三方用戶唯一憑證密鑰
        String appSecret = ConstantWeChat.APPSECRET;
        // 調(diào)用接口獲取access_token
        AccessToken at = CommonWechatUtil.getToken(appId, appSecret);
        if (null != at) {
            // 調(diào)用接口創(chuàng)建菜單
            int result = CommonWechatUtil.createMenu(getMenu(), at.getAccessToken());
            // 判斷菜單創(chuàng)建結(jié)果
            if (0 == result){
                LOGGER.info("菜單創(chuàng)建成功!");
                return true;
            }
            else{
                LOGGER.info("菜單創(chuàng)建失敗,錯(cuò)誤碼:" + result);
                return false;
            }
        }
        return false;
    }

    //    @Override
    public static JSONObject getMenuBtn() {
        // 第三方用戶唯一憑證
        String appId = ConstantWeChat.APPID;
        // 第三方用戶唯一憑證密鑰
        String appSecret = ConstantWeChat.APPSECRET;
        // 調(diào)用接口獲取access_token
        AccessToken at = CommonWechatUtil.getToken(appId, appSecret);
        if (null != at) {
            // 調(diào)用接口獲取菜單
            JSONObject result = CommonWechatUtil.getMenu(at.getAccessToken());
            // 判斷菜單創(chuàng)建結(jié)果
            if (null != result && result.size()>0){
                LOGGER.info("菜單查詢成功!");
                return result;
            }
            else{
                LOGGER.info("菜單查詢失敗,錯(cuò)誤碼:" + result);
                return null;
            }

        }
        return null;
    }

    //    @Override
    public static Boolean deleteMenu() {
        // 第三方用戶唯一憑證
        String appId = ConstantWeChat.APPID;
        // 第三方用戶唯一憑證密鑰
        String appSecret = ConstantWeChat.APPSECRET;
        // 調(diào)用接口獲取access_token
        AccessToken at = CommonWechatUtil.getToken(appId, appSecret);
        if (null != at) {
            // 調(diào)用接口刪除菜單
            int result = CommonWechatUtil.deleteMenu(at.getAccessToken());
            // 判斷菜單刪除結(jié)果
            if (0 == result){
                LOGGER.info("菜單刪除成功!");
                return true;
            }
            else{
                LOGGER.info("菜單刪除失敗,錯(cuò)誤碼:" + result);
                return false;
            }
        }
        return false;
    }

    /**
     * 組裝菜單數(shù)據(jù)
     *
     * @return
     * @throws UnsupportedEncodingException
     */
    private static Menu getMenu() {


        ViewButton btn11 = new ViewButton();
        btn11.setName("我是");
        btn11.setType("view");
        btn11.setUrl("https://segmentfault.com/u/panzi_5abcaf30a5e6b");

        ViewButton btn21 = new ViewButton();
        btn21.setName("盤子");
        btn21.setType("view");
        btn21.setUrl("https://segmentfault.com/u/panzi_5abcaf30a5e6b");

        ViewButton btn31 = new ViewButton();
        btn31.setName("謝謝");
        btn31.setType("view");
        btn31.setUrl("https://segmentfault.com/u/panzi_5abcaf30a5e6b");

        ViewButton btn41 = new ViewButton();
        btn41.setName("關(guān)注");
        btn41.setType("view");
        btn41.setUrl("https://segmentfault.com/u/panzi_5abcaf30a5e6b");

        CommonButton btn12 = new CommonButton();
        btn12.setName("贊");
        btn12.setType("click");
        btn12.setKey("return_content");

        ComplexButton mainBtn1 = new ComplexButton();
        mainBtn1.setName("自我介紹");
        mainBtn1.setSub_button(new BasicButton[] { btn11, btn21,btn31});

        ComplexButton mainBtn2 = new ComplexButton();
        mainBtn2.setName("謝謝!");
        mainBtn2.setSub_button(new BasicButton[] { btn41, btn12 });

        /**

         *在某個(gè)一級(jí)菜單下沒(méi)有二級(jí)菜單的情況,menu應(yīng)該這樣定義:
* menu.setButton(new Button[] { mainBtn1, mainBtn2, btn33 }); */ Menu menu = new Menu(); menu.setButton(new BasicButton[] { mainBtn1, mainBtn2}); return menu; } public static void main(String[] args) { createMenu(); } }

這里直接運(yùn)行main方法就好了
找到測(cè)試二維碼,掃描關(guān)注,可以看到菜單已經(jīng)有啦!!

如果修改了話,可以取消關(guān)注再添加關(guān)注,就能看到更改信息后的菜單信息。

對(duì)于菜單的點(diǎn)擊事件,可以回到我們的newMessageRequest方法中添加代碼:

// 自定義菜單點(diǎn)擊事件
else if (eventType.equals(MessageUtil.EVENT_TYPE_CLICK)) {
String eventKey = requestMap.get("EventKey");// 事件KEY值,與創(chuàng)建自定義菜單時(shí)指定的KEY值對(duì)應(yīng)
if (eventKey.equals("return_content")) {
  TextMessage text = new TextMessage();
  text.setContent("贊贊贊");
  text.setToUserName(fromUserName);
  text.setFromUserName(toUserName);
  text.setCreateTime(new Date().getTime());
  text.setMsgType(MessageUtil.RESP_MESSAGE_TYPE_TEXT);
  respMessage = MessageUtil.textMessageToXml(text);
  }
}

源碼地址:https://github.com/zhouminpz/...

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/35957.html

相關(guān)文章

  • java微信公眾號(hào)開(kāi)發(fā)):定義菜單實(shí)現(xiàn)

    摘要:想要實(shí)現(xiàn)自定義菜單的功能,需要有已認(rèn)證訂閱號(hào)和已認(rèn)證服務(wù)號(hào)。測(cè)試時(shí)可以嘗試取消關(guān)注公眾賬號(hào)后再次關(guān)注,則可以看到創(chuàng)建后的效果。 想要實(shí)現(xiàn)自定義菜單的功能,需要有已認(rèn)證訂閱號(hào)和已認(rèn)證服務(wù)號(hào)。對(duì)于測(cè)試開(kāi)發(fā)來(lái)說(shuō),可以直接申請(qǐng)一個(gè)測(cè)試賬號(hào):http://mp.weixin.qq.com/debug... 同樣需要token的驗(yàn)證,前期接口已經(jīng)定義好了,直接拿來(lái)就可以 showImg(https...

    Tony 評(píng)論0 收藏0
  • java微信公眾號(hào)開(kāi)發(fā)(一):前期準(zhǔn)備

    摘要:準(zhǔn)備寫(xiě)一個(gè)系列文章,記錄微信公眾號(hào)的開(kāi)發(fā)過(guò)程,也希望能為同為開(kāi)發(fā)的提供一些思路,不才,見(jiàn)諒。微信公眾號(hào)分為編輯模式和開(kāi)發(fā)者模式,一旦啟用了開(kāi)發(fā)者模式,前期的一些例如自動(dòng)回復(fù)菜單等會(huì)失效,望周知。 準(zhǔn)備寫(xiě)一個(gè)系列文章,記錄微信公眾號(hào)的開(kāi)發(fā)過(guò)程,也希望能為同為開(kāi)發(fā)的提供一些思路,不才,見(jiàn)諒。 微信公眾號(hào)分為編輯模式和開(kāi)發(fā)者模式,一旦啟用了開(kāi)發(fā)者模式,前期的一些例如自動(dòng)回復(fù)、菜單等會(huì)失效,望...

    fizz 評(píng)論0 收藏0
  • java微信公眾號(hào)開(kāi)發(fā)(一):前期準(zhǔn)備

    摘要:準(zhǔn)備寫(xiě)一個(gè)系列文章,記錄微信公眾號(hào)的開(kāi)發(fā)過(guò)程,也希望能為同為開(kāi)發(fā)的提供一些思路,不才,見(jiàn)諒。微信公眾號(hào)分為編輯模式和開(kāi)發(fā)者模式,一旦啟用了開(kāi)發(fā)者模式,前期的一些例如自動(dòng)回復(fù)菜單等會(huì)失效,望周知。 準(zhǔn)備寫(xiě)一個(gè)系列文章,記錄微信公眾號(hào)的開(kāi)發(fā)過(guò)程,也希望能為同為開(kāi)發(fā)的提供一些思路,不才,見(jiàn)諒。 微信公眾號(hào)分為編輯模式和開(kāi)發(fā)者模式,一旦啟用了開(kāi)發(fā)者模式,前期的一些例如自動(dòng)回復(fù)、菜單等會(huì)失效,望...

    cartoon 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<