当前位置: 移动技术网 > IT编程>开发语言>Java > java微信企业号开发之开发模式的开启

java微信企业号开发之开发模式的开启

2019年07月22日  | 移动技术网IT编程  | 我要评论

首先说微信企业号的开发模式分为:编辑模式(普通模式)开发模式(回调模式) ,在编辑模式下,只能做简单的自定义菜单和自动回复消息,要想实现其他功能还得开启开发者模式。

一、编辑模式和开发模式对消息的处理流程

 1.编辑模式下,所有的业务流程都配置在微信服务器上,由它处理

 

2.开发模式,消息通过第三方服务器处理,最后经过微信服务器把消息发送给用户

 

开发模式能处理的消息比编辑模式多,所以要先开启开发模式才能开发更多功能。

二、开发模式的开启

     在回调模式下,企业不仅可以主动调用企业号接口,还可以接收用户的消息或事件。接收的信息使用xml数据格式、utf8编码,并以aes方式加密

1.开启回调模式后要配置参数如下:

 

其中url是要访问的servlet,token和encodingaeskey是随机获取的,但要和项目中保持一致。

2.验证url的有效性

当你提交以上信息时,企业号将发送get请求到填写的url上,get请求携带四个参数,企业在获取时需要做urldecode处理,否则会验证不成功。

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://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;

/**
 * 提供接收和推送给公众平台消息的加解密接口(utf8编码的字符串).
 * <ol>
 * <li>第三方回复加密消息给公众平台</li>
 * <li>第三方收到公众平台发送的消息,验证消息的安全性,并对消息进行解密。</li>
 * </ol>
 * 说明:异常java.security.invalidkeyexception:illegal key size的解决方案
 * <ol>
 * <li>在官方网站下载jce无限制权限策略文件(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,将两个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明文(不能加引号),则接入验证生效,回调模式才能开启。开启后一些功能会陆续实现,敬请期待!

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持移动技术网。

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网