最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

java微信企業(yè)號(hào)開發(fā)之開發(fā)模式的開啟

 更新時(shí)間:2016年06月28日 09:22:34   作者:ggibenben1314  
這篇文章主要為大家詳細(xì)介紹了java微信企業(yè)號(hào)開發(fā)之開發(fā)模式的開啟方法,感興趣的小伙伴們可以參考一下

首先說(shuō)微信企業(yè)號(hào)的開發(fā)模式分為:編輯模式(普通模式)開發(fā)模式(回調(diào)模式) ,在編輯模式下,只能做簡(jiǎn)單的自定義菜單和自動(dòng)回復(fù)消息,要想實(shí)現(xiàn)其他功能還得開啟開發(fā)者模式。

一、編輯模式和開發(fā)模式對(duì)消息的處理流程

 1.編輯模式下,所有的業(yè)務(wù)流程都配置在微信服務(wù)器上,由它處理

 

2.開發(fā)模式,消息通過(guò)第三方服務(wù)器處理,最后經(jīng)過(guò)微信服務(wù)器把消息發(fā)送給用戶

 

開發(fā)模式能處理的消息比編輯模式多,所以要先開啟開發(fā)模式才能開發(fā)更多功能。

二、開發(fā)模式的開啟

     在回調(diào)模式下,企業(yè)不僅可以主動(dòng)調(diào)用企業(yè)號(hào)接口,還可以接收用戶的消息或事件。接收的信息使用XML數(shù)據(jù)格式、UTF8編碼,并以AES方式加密。

1.開啟回調(diào)模式后要配置參數(shù)如下:

 

其中url是要訪問(wèn)的servlet,token和EncodingAESKey是隨機(jī)獲取的,但要和項(xiàng)目中保持一致。

2.驗(yàn)證URL的有效性

當(dāng)你提交以上信息時(shí),企業(yè)號(hào)將發(fā)送GET請(qǐng)求到填寫的URL上,GET請(qǐng)求攜帶四個(gè)參數(shù),企業(yè)在獲取時(shí)需要做urldecode處理,否則會(huì)驗(yàn)證不成功。

3.代碼

CoreServlet1類 

public class CoreServlet1 extends HttpServlet {
 private static final long serialVersionUID = 4440739483644821986L;
 String sToken = "weixinCourse";
 String sCorpID = "wxe510946434680dab";
 String sEncodingAESKey = "DjlyZxgKiWRESIW2VnV9dSr7HsS7usWDfnwA8Q1ove1";
 
 public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
 
  WXBizMsgCrypt wxcpt;
 
   try {
 wxcpt = new WXBizMsgCrypt(sToken, sEncodingAESKey, sCorpID); 
 
 String sVerifyMsgSig = request.getParameter("msg_signature");
 
 String sVerifyTimeStamp = request.getParameter("timestamp"); 
 
 String sVerifyNonce = request.getParameter("nonce"); 
 
 String sVerifyEchoStr = request.getParameter("echostr");  
 String sEchoStr;
 
 sEchoStr = wxcpt.VerifyURL(sVerifyMsgSig, sVerifyTimeStamp,
   sVerifyNonce, sVerifyEchoStr);
 System.out.println("verifyurl echostr: " + sEchoStr);
 PrintWriter out = response.getWriter();
 out.print(sEchoStr); 
 out.close();
 out = null;
 
 } catch (AesException e1) {
 
 e1.printStackTrace();
 }
 
  }
}

工具類:

 /**
 * 對(duì)公眾平臺(tái)發(fā)送給公眾賬號(hào)的消息加解密示例代碼.
 * 
 * @copyright Copyright (c) 1998-2014 Tencent Inc.
 */

// ------------------------------------------------------------------------

/**
 * 針對(duì)org.apache.commons.codec.binary.Base64,
 * 需要導(dǎo)入架包c(diǎn)ommons-codec-1.9(或commons-codec-1.8等其他版本)
 * 官方下載地址:http://commons.apache.org/proper/commons-codec/download_codec.cgi
 */
package com.qq.weixin.mp.aes;

import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.Random;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.codec.binary.Base64;

/**
 * 提供接收和推送給公眾平臺(tái)消息的加解密接口(UTF8編碼的字符串).
 * <ol>
 * <li>第三方回復(fù)加密消息給公眾平臺(tái)</li>
 * <li>第三方收到公眾平臺(tái)發(fā)送的消息,驗(yàn)證消息的安全性,并對(duì)消息進(jìn)行解密。</li>
 * </ol>
 * 說(shuō)明:異常java.security.InvalidKeyException:illegal Key Size的解決方案
 * <ol>
 * <li>在官方網(wǎng)站下載JCE無(wú)限制權(quán)限策略文件(JDK7的下載地址:
 *   http://www.oracle.com/technetwork/java/javase/downloads/jce-7-download-432124.html</li>
 * <li>下載后解壓,可以看到local_policy.jar和US_export_policy.jar以及readme.txt</li>
 * <li>如果安裝了JRE,將兩個(gè)jar文件放到%JRE_HOME%\lib\security目錄下覆蓋原來(lái)的文件</li>
 * <li>如果安裝了JDK,將兩個(gè)jar文件放到%JDK_HOME%\jre\lib\security目錄下覆蓋原來(lái)文件</li>
 * </ol>
 */
public class WXBizMsgCrypt {
 static Charset CHARSET = Charset.forName("utf-8");
 Base64 base64 = new Base64();
 byte[] aesKey;
 String token;
 String corpId;

 /**
 * 構(gòu)造函數(shù)
 * @param token 公眾平臺(tái)上,開發(fā)者設(shè)置的token
 * @param encodingAesKey 公眾平臺(tái)上,開發(fā)者設(shè)置的EncodingAESKey
 * @param corpId 企業(yè)的corpid
 * 
 * @throws AesException 執(zhí)行失敗,請(qǐng)查看該異常的錯(cuò)誤碼和具體的錯(cuò)誤信息
 */
 public WXBizMsgCrypt(String token, String encodingAesKey, String corpId) throws AesException {
 if (encodingAesKey.length() != 43) {
  throw new AesException(AesException.IllegalAesKey);
 }

 this.token = token;
 this.corpId = corpId;
 aesKey = Base64.decodeBase64(encodingAesKey + "=");
 }

 
 

 /**
 * 對(duì)密文進(jìn)行解密.
 * 
 * @param text 需要解密的密文
 * @return 解密得到的明文
 * @throws AesException aes解密失敗
 */
 String decrypt(String text) throws AesException {
 byte[] original;
 try {
  // 設(shè)置解密模式為AES的CBC模式
  Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
  SecretKeySpec key_spec = new SecretKeySpec(aesKey, "AES");
  IvParameterSpec iv = new IvParameterSpec(Arrays.copyOfRange(aesKey, 0, 16));
  cipher.init(Cipher.DECRYPT_MODE, key_spec, iv);

  // 使用BASE64對(duì)密文進(jìn)行解碼
  byte[] encrypted = Base64.decodeBase64(text);

  // 解密
  original = cipher.doFinal(encrypted);
 } catch (Exception e) {
  e.printStackTrace();
  throw new AesException(AesException.DecryptAESError);
 }

 String xmlContent, from_corpid;
 try {
  // 去除補(bǔ)位字符
  byte[] bytes = PKCS7Encoder.decode(original);

  // 分離16位隨機(jī)字符串,網(wǎng)絡(luò)字節(jié)序和corpId
  byte[] networkOrder = Arrays.copyOfRange(bytes, 16, 20);

  int xmlLength = recoverNetworkBytesOrder(networkOrder);

  xmlContent = new String(Arrays.copyOfRange(bytes, 20, 20 + xmlLength), CHARSET);
  from_corpid = new String(Arrays.copyOfRange(bytes, 20 + xmlLength, bytes.length),
   CHARSET);
 } catch (Exception e) {
  e.printStackTrace();
  throw new AesException(AesException.IllegalBuffer);
 }

 // corpid不相同的情況
 if (!from_corpid.equals(corpId)) {
  throw new AesException(AesException.ValidateCorpidError);
 }
 return xmlContent;

 }


 /**
 * 驗(yàn)證URL
 * @param msgSignature 簽名串,對(duì)應(yīng)URL參數(shù)的msg_signature
 * @param timeStamp 時(shí)間戳,對(duì)應(yīng)URL參數(shù)的timestamp
 * @param nonce 隨機(jī)串,對(duì)應(yīng)URL參數(shù)的nonce
 * @param echoStr 隨機(jī)串,對(duì)應(yīng)URL參數(shù)的echostr
 * 
 * @return 解密之后的echostr
 * @throws AesException 執(zhí)行失敗,請(qǐng)查看該異常的錯(cuò)誤碼和具體的錯(cuò)誤信息
 */
 public String VerifyURL(String msgSignature, String timeStamp, String nonce, String echoStr)
  throws AesException {
 String signature = SHA1.getSHA1(token, timeStamp, nonce, echoStr);

 if (!signature.equals(msgSignature)) {
  throw new AesException(AesException.ValidateSignatureError);
 }

 String result = decrypt(echoStr);
 return result;
 }

}
 /**
 * 對(duì)公眾平臺(tái)發(fā)送給公眾賬號(hào)的消息加解密示例代碼.
 * 
 * @copyright Copyright (c) 1998-2014 Tencent Inc.
 */

// ------------------------------------------------------------------------

package com.qq.weixin.mp.aes;

import java.security.MessageDigest;
import java.util.Arrays;

/**
 * SHA1 class
 *
 * 計(jì)算公眾平臺(tái)的消息簽名接口.
 */
class SHA1 {

 /**
 * 用SHA1算法生成安全簽名
 * @param token 票據(jù)
 * @param timestamp 時(shí)間戳
 * @param nonce 隨機(jī)字符串
 * @param encrypt 密文
 * @return 安全簽名
 * @throws AesException 
 */
 public static String getSHA1(String token, String timestamp, String nonce, String encrypt) throws AesException
   {
 try {
  String[] array = new String[] { token, timestamp, nonce, encrypt };
  StringBuffer sb = new StringBuffer();
  // 字符串排序
  Arrays.sort(array);
  for (int i = 0; i < 4; i++) {
  sb.append(array[i]);
  }
  String str = sb.toString();
  // SHA1簽名生成
  MessageDigest md = MessageDigest.getInstance("SHA-1");
  md.update(str.getBytes());
  byte[] digest = md.digest();

  StringBuffer hexstr = new StringBuffer();
  String shaHex = "";
  for (int i = 0; i < digest.length; i++) {
  shaHex = Integer.toHexString(digest[i] & 0xFF);
  if (shaHex.length() < 2) {
   hexstr.append(0);
  }
  hexstr.append(shaHex);
  }
  return hexstr.toString();
 } catch (Exception e) {
  e.printStackTrace();
  throw new AesException(AesException.ComputeSignatureError);
 }
 }
}

 class PKCS7Encoder {
 static Charset CHARSET = Charset.forName("utf-8");
 static int BLOCK_SIZE = 32;
/**
 * 刪除解密后明文的補(bǔ)位字符
 * 
 * @param decrypted 解密后的明文
 * @return 刪除補(bǔ)位字符后的明文
 */
 static byte[] decode(byte[] decrypted) {
 int pad = (int) decrypted[decrypted.length - 1];
 if (pad < 1 || pad > 32) {
  pad = 0;
 }
 return Arrays.copyOfRange(decrypted, 0, decrypted.length - pad);
 }
}

三、總結(jié)
企業(yè)通過(guò)參數(shù)msg_signature對(duì)請(qǐng)求進(jìn)行校驗(yàn),如果確認(rèn)此次GET請(qǐng)求來(lái)自企業(yè)號(hào),那么企業(yè)應(yīng)用對(duì)echostr參數(shù)解密并原樣返回echostr明文(不能加引號(hào)),則接入驗(yàn)證生效,回調(diào)模式才能開啟。開啟后一些功能會(huì)陸續(xù)實(shí)現(xiàn),敬請(qǐng)期待!

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Spring?Security實(shí)現(xiàn)添加圖片驗(yàn)證功能

    Spring?Security實(shí)現(xiàn)添加圖片驗(yàn)證功能

    這篇文章主要為大家介紹了Spring?Security實(shí)現(xiàn)添加圖片驗(yàn)證功能詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-01-01
  • 解決@CachePut設(shè)置的key值無(wú)法與@CacheValue的值匹配問(wèn)題

    解決@CachePut設(shè)置的key值無(wú)法與@CacheValue的值匹配問(wèn)題

    這篇文章主要介紹了解決@CachePut設(shè)置的key的值無(wú)法與@CacheValue的值匹配問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • Spring?Data?Exists查詢最佳方法編寫示例

    Spring?Data?Exists查詢最佳方法編寫示例

    這篇文章主要為大家介紹了Spring?Data?Exists查詢最佳方法編寫示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08
  • Java foreach循環(huán)是否可以修改數(shù)據(jù)的值問(wèn)題解決方法

    Java foreach循環(huán)是否可以修改數(shù)據(jù)的值問(wèn)題解決方法

    最近在做項(xiàng)目的時(shí)候,需要修改一個(gè)數(shù)組里面各個(gè)元素的值,foreach循環(huán)迭代數(shù)組元素時(shí),不能改變數(shù)組元素的值,這篇文章給大家介紹Java foreach循環(huán)是否可以修改數(shù)據(jù)的值的問(wèn)題及解決方法,感興趣的朋友一起看看吧
    2024-02-02
  • SpringBoot整合任務(wù)系統(tǒng)quartz和SpringTask的方法

    SpringBoot整合任務(wù)系統(tǒng)quartz和SpringTask的方法

    這篇文章主要介紹了SpringBoot整合任務(wù)系統(tǒng)(quartz和SpringTask),Quartz是一個(gè)比較成熟了的定時(shí)任務(wù)框架,但是捏,它稍微的有些許繁瑣,本文先給大家講解下Quartz的一些基本概念結(jié)合實(shí)例代碼給大家詳細(xì)講解,需要的朋友可以參考下
    2022-10-10
  • IDEA的maven設(shè)置代理方式

    IDEA的maven設(shè)置代理方式

    文章介紹了如何設(shè)置IntelliJ?IDEA系統(tǒng)代理,并在Maven的Importing和Runner中添加代理配置,包括設(shè)置代理主機(jī)和端口
    2025-01-01
  • SpringBoot開啟server:compression:enabled(Illegal character ((CTRL-CHAR, code 31)))的問(wèn)題解決

    SpringBoot開啟server:compression:enabled(Illegal characte

    本文主要介紹了SpringBoot開啟server:compression:enabled(Illegal character ((CTRL-CHAR, code 31)))的的問(wèn)題解決,具有一定的參考價(jià)值,感興趣的可以了解一下
    2025-03-03
  • 使用profiles進(jìn)行多環(huán)境配置的代碼實(shí)現(xiàn)

    使用profiles進(jìn)行多環(huán)境配置的代碼實(shí)現(xiàn)

    在項(xiàng)目開發(fā)的過(guò)程中會(huì)用到多個(gè)環(huán)境,為了便于開發(fā)使用,通常需要使用profiles進(jìn)行多環(huán)境配置,所以本文給大家介紹了使用profiles進(jìn)行多環(huán)境配置的代碼實(shí)現(xiàn),需要的朋友可以參考下
    2024-02-02
  • 解讀SpringBoot為什么要用DeferredImportSelector

    解讀SpringBoot為什么要用DeferredImportSelector

    這篇文章主要介紹了SpringBoot為什么要用DeferredImportSelector的情況,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2025-03-03
  • SSM如何實(shí)現(xiàn)在Controller中添加事務(wù)管理

    SSM如何實(shí)現(xiàn)在Controller中添加事務(wù)管理

    這篇文章主要介紹了SSM如何實(shí)現(xiàn)在Controller中添加事務(wù)管理,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-02-02

最新評(píng)論

紫阳县| 界首市| 阜平县| 凤山市| 崇仁县| 大足县| 连云港市| 福海县| 铜山县| 盱眙县| 平顺县| 运城市| 凤山县| 增城市| 哈尔滨市| 高阳县| 田林县| 辽阳县| 达日县| 锦屏县| 大足县| 乌拉特后旗| 沅江市| 阳高县| 鄢陵县| 吉隆县| 舞钢市| 宕昌县| 上饶县| 溆浦县| 大竹县| 田东县| 竹北市| 黄冈市| 开远市| 即墨市| 时尚| 柳河县| 泌阳县| 色达县| 本溪|