詳解java微信企業號開發之開發模式的開啟步驟

高洛峰
發布: 2017-03-15 17:49:07
原創
2453 人瀏覽過

這篇文章主要為大家詳細介紹了java微信企業號開發之開發模式的開啟方法,感興趣的小伙伴們可以參考一下

首先說微信企業號的開發模式分為: 編輯模式(普通模式)開發模式(回呼模式) ,在編輯模式下,只能做簡單的自訂選單和自動回覆訊息,要實現其他功能還得開啟開發者模式。

一、編輯模式與開發模式對訊息的處理流程

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

  詳解java微信企業號開發之開發模式的開啟步驟

2.開發模式,訊息透過第三方伺服器處理,最後經過微信伺服器把訊息傳送給使用者

  詳解java微信企業號開發之開發模式的開啟步驟

開發模式能處理的訊息比編輯模式多,所以要先開啟開發模式才能開發更多功能。

二、開發模式的開啟

     在回呼模式下,企業不僅可以主動呼叫企業號介面,還能接收使用者的訊息或事件接收的資訊使用XML資料格式、UTF8編碼,並以AES方式加密

1.開啟回呼模式後要設定參數如下:

  詳解java微信企業號開發之開發模式的開啟步驟

其中url是要存取的servlet,token和EncodingAESKey是隨機取得的,但要和專案中保持一致。

2.驗證URL的有效性

當你提交以上資訊時,企業號將發送GET請求到填寫的URL上,GET請求攜帶四個參數,企業在取得時需要做urldecode處理,否則會驗證不成功。

詳解java微信企業號開發之開發模式的開啟步驟

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();
 }
 
  }
}
登入後複製

工具類:

 /**
 * 对公众平台发送给公众账号的消息加解密示例代码.
 * 
 * @copyright Copyright (c) 1998-2014 Tencent Inc.
 */

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

/**
 * 针对org.apache.commons.codec.binary.Base64,
 * 需要导入架包commons-codec-1.9(或commons-codec-1.8等其他版本)
 * 官方下载地址:http://www.php.cn/
 */
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;

/**
 * 提供接收和推送给公众平台消息的加解密接口(UTF8编码的字符串).
 * <ol>
 * <li>第三方回复加密消息给公众平台</li>
 * <li>第三方收到公众平台发送的消息,验证消息的安全性,并对消息进行解密。</li>
 * </ol>
 * 说明:异常java.security.InvalidKeyException:illegal Key Size的解决方案
 * <ol>
 * <li>在官方网站下载JCE无限制权限策略文件(JDK7的下载地址:
 *   http://www.php.cn/;/li>
 * <li>下载后解压,可以看到local_policy.jar和US_export_policy.jar以及readme.txt</li>
 * <li>如果安装了JRE,将两个jar文件放到%JRE_HOME%\lib\security目录下覆盖原来的文件</li>
 * <li>如果安装了JDK,将两个jar文件放到%JDK_HOME%\jre\lib\security目录下覆盖原来文件</li>
 * </ol>
 */
public class WXBizMsgCrypt {
 static Charset CHARSET = Charset.forName("utf-8");
 Base64 base64 = new Base64();
 byte[] aesKey;
 String token;
 String corpId;

 /**
 * 构造函数
 * @param token 公众平台上,开发者设置的token
 * @param encodingAesKey 公众平台上,开发者设置的EncodingAESKey
 * @param corpId 企业的corpid
 * 
 * @throws AesException 执行失败,请查看该异常的错误码和具体的错误信息
 */
 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 + "=");
 }

 
 

 /**
 * 对密文进行解密.
 * 
 * @param text 需要解密的密文
 * @return 解密得到的明文
 * @throws AesException aes解密失败
 */
 String decrypt(String text) throws AesException {
 byte[] original;
 try {
  // 设置解密模式为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对密文进行解码
  byte[] encrypted = Base64.decodeBase64(text);

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

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

  // 分离16位随机字符串,网络字节序和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;

 }


 /**
 * 验证URL
 * @param msgSignature 签名串,对应URL参数的msg_signature
 * @param timeStamp 时间戳,对应URL参数的timestamp
 * @param nonce 随机串,对应URL参数的nonce
 * @param echoStr 随机串,对应URL参数的echostr
 * 
 * @return 解密之后的echostr
 * @throws AesException 执行失败,请查看该异常的错误码和具体的错误信息
 */
 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;
 }

}
 /**
 * 对公众平台发送给公众账号的消息加解密示例代码.
 * 
 * @copyright Copyright (c) 1998-2014 Tencent Inc.
 */

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

package com.qq.weixin.mp.aes;

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

/**
 * SHA1 class
 *
 * 计算公众平台的消息签名接口.
 */
class SHA1 {

 /**
 * 用SHA1算法生成安全签名
 * @param token 票据
 * @param timestamp 时间戳
 * @param nonce 随机字符串
 * @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;
/**
 * 删除解密后明文的补位字符
 * 
 * @param decrypted 解密后的明文
 * @return 删除补位字符后的明文
 */
 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);
 }
}
登入後複製

三、總結
企業透過參數msg_signature對請求進行校驗,若確認此GET請求來自企業號,那麼企業應用程式對echostr參數解密並原樣回傳echostr明文(不能加引號),則存取驗證生效,回呼模式才能開啟。開啟後一些功能會陸續實現,敬請期待!


以上是詳解java微信企業號開發之開發模式的開啟步驟的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
最新問題
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!