java对接企业微信

java对接企业微信

一、注册企业微信

1.1 简介

  企业微信与微信具有一样的体验,通过企业内部与外部客户的管理,构建出社群生态。企业微信提供丰富的api进行调用获取数据管理,也提供各种回调事件。

1.2 注册

  登录官网,一键注册即可。链接: 企业微信

1.2 填写主要信息

  企业微信中填写相关企业信息和负责人,然后创建。进入即可添加所需要的微信人员。
请添加图片描述

  之后进行通讯录同步(此步骤为最重要一点),同步过后通讯录的人员根据调用接口接收消息。
请添加图片描述

1.3 创建应用

  创建自己需要的应用,并根据提示创建应用(也可以不创建,用以前有的应用作为发送消息的主体也可以)
请添加图片描述

二、企业微信基础信息

  创建完企业微信和自己所需要的应用后,需要记住几处重要的参数,方便后续调用api使用。
请添加图片描述
请添加图片描述

  简单介绍几个参数:(需存入数据库)
1.企业id:当前企业微信的固定id;
2.agentid:当前自建应用id;
3.secret:应用秘钥,调用验证秘钥;

注:企业应用的可见范围需添加微信中的人员表。为后续调用查询、发送人员作限定选择。

三、消息接收url机制-回调

  在java集成企业微信的同时,需要一个回调服务。现可以实现:
自定义丰富的服务行为、可以及时获取状态变化。
在这里插入图片描述
  通过企业微信服务器向后端服务器发送各种需要消息。
这里只讲配置建立消息接收url机制。
请添加图片描述
请添加图片描述
  附录上述两张图,其中包含设置可信ip(开发服务器的ip,为了服务器调用api)、配置接收服务器(通过回调机制+配置,验证url是否能接收到消息,并返回企业微信所需要的信息来校验)。加密解密见附录五。
回调配置
请添加图片描述
能通过发送来的密文(附录5中具体解密),返回给企业微信端需要的密文。即可通过校验,然后就可以填写认证ip进行开发调用接口。

  简单介绍几个参数:(需存入数据库)
1.url:接收企业微信消息的接口
2.token:计算签名(可在配置中随机生成)
3.encoding_aes_key:加密key(加解密使用)

四、java对接企业微信(自建应用)

  在上几个步骤中,我们已有需求的5个参数配置。根据这5个参数就可以进行与java对接。
请添加图片描述

4.1 对接前提(获取access_token)

在这里插入图片描述
token是调用接口的基础。根据之前的保存参数即可获取。以下展示为项目所需接口调用,其他接口使用token基本都能调用。

4.2 手机号获取userid

在这里插入图片描述

4.3 发送应用消息

在这里插入图片描述
在这里插入图片描述
本文只展示文本方面,其他发送信息方面可参照api接口。api接口

五、附加-校验加密解密方式

5.1 方案说明

请添加图片描述

请添加图片描述
请添加图片描述

5.2 代码实例

/*** @Author sprem至尊* @Date 2022/10/21 16:43* @Version 1.0*/
package com.example.demo.controller;import com.example.demo.aes.WXBizJsonMsgCrypt;
import com.example.demo.cache.TokenCache;
import com.example.demo.entity.TestEntity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class TestController {@Autowiredprivate TokenCache tokenCache;@RequestMapping("/")private String home(TestEntity testEntity) {//postman的参数放在form-data中 不然特殊符号会变空格String sToken = "axBoJ9yw3NeLPffBNUTQlfXiP612Xdpw";//SSrYt12q2KL  QDG6eKString sCorpID = "ww1ca8f5fe0f582941e9";//""wwca8f511fe0f58941e9"; wx5823bf96d3bd561c7String sEncodingAESKey = "Sb8eDJndNDPjIyzqFzMI2sKtOfgoCYMrIWjqu2m1ql3Vb";// W5UBw9XoqW61HPfL7TUsI4qC2myJrw3MQ9bDrbDsWWQ2//jWmYm7qr5nMoAUwZRjGtBxmz3K4A1tkAj3ykkR6q2B2CString sVerifyMsgSig = testEntity.getMsg_signature();String sVerifyTimeStamp = testEntity.getTimestamp();String sVerifyNonce = testEntity.getNonce();String sVerifyEchoStr = testEntity.getEchostr();String sEchoStr ="";//明文try {//获取其中 aesKeyWXBizJsonMsgCrypt wxcpt = new WXBizJsonMsgCrypt(sToken, sEncodingAESKey, sCorpID);//获取明文sEchoStr = wxcpt.VerifyURL(sVerifyMsgSig,sVerifyTimeStamp,sVerifyNonce,sVerifyEchoStr);System.out.println("verifyurl echostr: " + sEchoStr);}catch (Exception e){e.printStackTrace();}return sEchoStr;}@RequestMapping("/testCache")private String testCache() {String s = TokenCache.getValue("s1111");if(s==null){System.out.println("时间过期");TokenCache.setKey("s12111","1243123123");s =TokenCache.getValue("s12111");}System.out.println(s);return "sss";}
}
/*** @Author sprem至尊* @Date 2022/10/21 17:00* @Version 1.0*/
package com.example.demo.entity;
import lombok.Data;
@Data
public class TestEntity {private String msg_signature;private String timestamp;private String nonce;private String echostr;
}
package com.example.demo.aes;@SuppressWarnings("serial")
public class AesException extends Exception {public final static int OK = 0;public final static int ValidateSignatureError = -40001;public final static int ParseJsonError = -40002;public final static int ComputeSignatureError = -40003;public final static int IllegalAesKey = -40004;public final static int ValidateCorpidError = -40005;public final static int EncryptAESError = -40006;public final static int DecryptAESError = -40007;public final static int IllegalBuffer = -40008;public final static int EncodeBase64Error = -40009;public final static int DecodeBase64Error = -40010;public final static int GenReturnJsonError = -40011;private int code;private static String getMessage(int code) {switch (code) {case ValidateSignatureError:return "签名验证错误";case ParseJsonError:return "json解析失败";case ComputeSignatureError:return "sha加密生成签名失败";case IllegalAesKey:return "SymmetricKey非法";case ValidateCorpidError:return "corpid校验失败";case EncryptAESError:return "aes加密失败";case DecryptAESError:return "aes解密失败";case IllegalBuffer:return "解密后得到的buffer非法";case EncodeBase64Error:return "base64加密错误";case DecodeBase64Error:return "base64解密错误";case GenReturnJsonError:return "josn生成失败";default:return null; // cannot be}}public int getCode() {return code;}AesException(int code) {super(getMessage(code));this.code = code;}}
package com.example.demo.aes;import java.util.ArrayList;class ByteGroup {ArrayList<Byte> byteContainer = new ArrayList<Byte>();public byte[] toBytes() {byte[] bytes = new byte[byteContainer.size()];for (int i = 0; i < byteContainer.size(); i++) {bytes[i] = byteContainer.get(i);}return bytes;}public ByteGroup addBytes(byte[] bytes) {for (byte b : bytes) {byteContainer.add(b);}return this;}public int size() {return byteContainer.size();}
}
/*** 对企业微信发送给企业后台的消息加解密示例代码.* * @copyright Copyright (c) 1998-2020 Tencent Inc.*/// ------------------------------------------------------------------------package com.example.demo.aes;/*** 针对 org.json.JSONObject,* 要编译打包架包json* 官方源码下载地址 : https://github.com/stleary/JSON-java, jar包下载地址 : https://mvnrepository.com/artifact/org.json/json*/
import org.json.JSONObject;/*** JsonParse class** 提供提取消息格式中的密文及生成回复消息格式的接口.*/
class JsonParse {/*** 提取出 JSON 包中的加密消息* @param jsontext 待提取的json字符串* @return 提取出的加密消息字符串* @throws AesException */public static Object[] extract(String jsontext) throws AesException     {Object[] result = new Object[3];try {JSONObject json = new JSONObject(jsontext);    String encrypt_msg = json.getString("encrypt");String tousername  = json.getString("tousername");String agentid     = json.getString("agentid");result[0] = tousername;result[1] = encrypt_msg;result[2] = agentid;return result;} catch (Exception e) {e.printStackTrace();throw new AesException(AesException.ParseJsonError);}}/*** 生成json消息* @param encrypt 加密后的消息密文* @param signature 安全签名* @param timestamp 时间戳* @param nonce 随机字符串* @return 生成的json字符串*/public static String generate(String encrypt, String signature, String timestamp, String nonce) {String format = "{\"encrypt\":\"%1$s\",\"msgsignature\":\"%2$s\",\"timestamp\":\"%3$s\",\"nonce\":\"%4$s\"}";return String.format(format, encrypt, signature, timestamp, nonce);}
}
/*** 对企业微信发送给企业后台的消息加解密示例代码.* * @copyright Copyright (c) 1998-2014 Tencent Inc.*/// ------------------------------------------------------------------------package com.example.demo.aes;import java.nio.charset.Charset;
import java.util.Arrays;/*** 提供基于PKCS7算法的加解密接口.*/
class PKCS7Encoder {static Charset CHARSET = Charset.forName("utf-8");static int BLOCK_SIZE = 32;/*** 获得对明文进行补位填充的字节.* * @param count 需要进行填充补位操作的明文字节个数* @return 补齐用的字节数组*/static byte[] encode(int count) {// 计算需要填充的位数int amountToPad = BLOCK_SIZE - (count % BLOCK_SIZE);if (amountToPad == 0) {amountToPad = BLOCK_SIZE;}// 获得补位所用的字符char padChr = chr(amountToPad);String tmp = new String();for (int index = 0; index < amountToPad; index++) {tmp += padChr;}return tmp.getBytes(CHARSET);}/*** 删除解密后明文的补位字符* * @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);}/*** 将数字转化成ASCII码对应的字符,用于对明文进行补码* * @param a 需要转化的数字* @return 转化得到的字符*/static char chr(int a) {byte target = (byte) (a & 0xFF);return (char) target;}}
/*** 对企业微信发送给企业后台的消息加解密示例代码.* * @copyright Copyright (c) 1998-2014 Tencent Inc.*/// ------------------------------------------------------------------------package com.example.demo.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);}}
}
/*** 对企业微信发送给企业后台的消息加解密示例代码.* * @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.example.demo.aes;import org.apache.commons.codec.binary.Base64;import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.Random;/*** 提供接收和推送给企业微信消息的加解密接口(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 WXBizJsonMsgCrypt {static Charset CHARSET = Charset.forName("utf-8");Base64 base64 = new Base64();byte[] aesKey;String token;String receiveid;/*** 构造函数* @param token 企业微信后台,开发者设置的token* @param encodingAesKey 企业微信后台,开发者设置的EncodingAESKey* @param receiveid, 不同场景含义不同,详见文档* * @throws AesException 执行失败,请查看该异常的错误码和具体的错误信息*/public WXBizJsonMsgCrypt(String token, String encodingAesKey, String receiveid) throws AesException {if (encodingAesKey.length() != 43) {throw new AesException(AesException.IllegalAesKey);}this.token = token;this.receiveid = receiveid;aesKey = Base64.decodeBase64(encodingAesKey + "=");}// 生成4个字节的网络字节序byte[] getNetworkBytesOrder(int sourceNumber) {byte[] orderBytes = new byte[4];orderBytes[3] = (byte) (sourceNumber & 0xFF);orderBytes[2] = (byte) (sourceNumber >> 8 & 0xFF);orderBytes[1] = (byte) (sourceNumber >> 16 & 0xFF);orderBytes[0] = (byte) (sourceNumber >> 24 & 0xFF);return orderBytes;}// 还原4个字节的网络字节序int recoverNetworkBytesOrder(byte[] orderBytes) {int sourceNumber = 0;for (int i = 0; i < 4; i++) {sourceNumber <<= 8;sourceNumber |= orderBytes[i] & 0xff;}return sourceNumber;}// 随机生成16位字符串String getRandomStr() {String base = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";Random random = new Random();StringBuffer sb = new StringBuffer();for (int i = 0; i < 16; i++) {int number = random.nextInt(base.length());sb.append(base.charAt(number));}return sb.toString();}/*** 对明文进行加密.* * @param text 需要加密的明文* @return 加密后base64编码的字符串* @throws AesException aes加密失败*/String encrypt(String randomStr, String text) throws AesException {ByteGroup byteCollector = new ByteGroup();byte[] randomStrBytes = randomStr.getBytes(CHARSET);byte[] textBytes = text.getBytes(CHARSET);byte[] networkBytesOrder = getNetworkBytesOrder(textBytes.length);byte[] receiveidBytes = receiveid.getBytes(CHARSET);// randomStr + networkBytesOrder + text + receiveidbyteCollector.addBytes(randomStrBytes);byteCollector.addBytes(networkBytesOrder);byteCollector.addBytes(textBytes);byteCollector.addBytes(receiveidBytes);// ... + pad: 使用自定义的填充方式对明文进行补位填充byte[] padBytes = PKCS7Encoder.encode(byteCollector.size());byteCollector.addBytes(padBytes);// 获得最终的字节流, 未加密byte[] unencrypted = byteCollector.toBytes();try {// 设置加密模式为AES的CBC模式Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");SecretKeySpec keySpec = new SecretKeySpec(aesKey, "AES");IvParameterSpec iv = new IvParameterSpec(aesKey, 0, 16);cipher.init(Cipher.ENCRYPT_MODE, keySpec, iv);// 加密byte[] encrypted = cipher.doFinal(unencrypted);// 使用BASE64对加密后的字符串进行编码String base64Encrypted = base64.encodeToString(encrypted);return base64Encrypted;} catch (Exception e) {e.printStackTrace();throw new AesException(AesException.EncryptAESError);}}/*** 对密文进行解密.* * @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 jsonContent, from_receiveid;try {// 去除补位字符byte[] bytes = PKCS7Encoder.decode(original);// 分离16位随机字符串,网络字节序和receiveidbyte[] networkOrder = Arrays.copyOfRange(bytes, 16, 20);int jsonLength = recoverNetworkBytesOrder(networkOrder);jsonContent = new String(Arrays.copyOfRange(bytes, 20, 20 + jsonLength), CHARSET);from_receiveid = new String(Arrays.copyOfRange(bytes, 20 + jsonLength, bytes.length),CHARSET);} catch (Exception e) {e.printStackTrace();throw new AesException(AesException.IllegalBuffer);}// receiveid不相同的情况if (!from_receiveid.equals(receiveid)) {throw new AesException(AesException.ValidateCorpidError);}return jsonContent;}/*** 将企业微信回复用户的消息加密打包.* <ol>* 	<li>对要发送的消息进行AES-CBC加密</li>* 	<li>生成安全签名</li>* 	<li>将消息密文和安全签名打包成json格式</li>* </ol>* * @param replyMsg 企业微信待回复用户的消息,json格式的字符串* @param timeStamp 时间戳,可以自己生成,也可以用URL参数的timestamp* @param nonce 随机串,可以自己生成,也可以用URL参数的nonce* * @return 加密后的可以直接回复用户的密文,包括msg_signature, timestamp, nonce, encrypt的json格式的字符串* @throws AesException 执行失败,请查看该异常的错误码和具体的错误信息*/public String EncryptMsg(String replyMsg, String timeStamp, String nonce) throws AesException {// 加密String encrypt = encrypt(getRandomStr(), replyMsg);// 生成安全签名if (timeStamp == "") {timeStamp = Long.toString(System.currentTimeMillis());}String signature = SHA1.getSHA1(token, timeStamp, nonce, encrypt);// System.out.println("发送给平台的签名是: " + signature[1].toString());// 生成发送的jsonString result = JsonParse.generate(encrypt, signature, timeStamp, nonce);return result;}/*** 检验消息的真实性,并且获取解密后的明文.* <ol>* 	<li>利用收到的密文生成安全签名,进行签名验证</li>* 	<li>若验证通过,则提取json中的加密消息</li>* 	<li>对消息进行解密</li>* </ol>* * @param msgSignature 签名串,对应URL参数的msg_signature* @param timeStamp 时间戳,对应URL参数的timestamp* @param nonce 随机串,对应URL参数的nonce* @param postData 密文,对应POST请求的数据* * @return 解密后的原文* @throws AesException 执行失败,请查看该异常的错误码和具体的错误信息*/public String DecryptMsg(String msgSignature, String timeStamp, String nonce, String postData)throws AesException {// 密钥,公众账号的app secret// 提取密文Object[] encrypt = JsonParse.extract(postData);// 验证安全签名String signature = SHA1.getSHA1(token, timeStamp, nonce, encrypt[1].toString());// 和URL中的签名比较是否相等// System.out.println("第三方收到URL中的签名:" + msg_sign);// System.out.println("第三方校验签名:" + signature);if (!signature.equals(msgSignature)) {throw new AesException(AesException.ValidateSignatureError);}// 解密String result = decrypt(encrypt[1].toString());return result;}/*** 验证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;}
}
/*** @Author sprem至尊* @Date 2022/10/24 17:55* @Version 1.0*/
package com.example.demo.cache;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import org.springframework.stereotype.Component;
import java.util.concurrent.TimeUnit;
@Component
public class TokenCache {private static LoadingCache<String,String> loadingCache = CacheBuilder.newBuilder().initialCapacity(100).maximumSize(100).expireAfterWrite(5, TimeUnit.SECONDS).build(new CacheLoader<String, String>() {@Overridepublic String load(String key) throws Exception {System.out.println("loadkey::::"+key);System.out.println("loadValue::::"+getValue(key));return null;}});public static void setKey(String key,String value){loadingCache.put(key, value);}public static String getValue(String key){String value = null;try{value = loadingCache.get(key);if(value == null){return null;}return value;}catch (Exception e){return null;}}
}

六、附加-对接第三方应用

可在开发中心详细查看,这里不做过多介绍,如后续项目需使用,即可添加。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/254424.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

微信 JSAPI 支付流程

微信支付&#xff0c;开发文档地址&#xff1a; https://pay.weixin.qq.com/wiki/doc/api/index.html JSAPI支付文档地址&#xff1a; https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter9_2 微信支付分为5种&#xff1a; Jsapi支付&#xff0c;二维码支付&#xf…

android 仿微信demo————注册功能完善添加头像功能(移动端)

android 仿微信demo————微信启动界面实现 android 仿微信demo————注册功能实现&#xff08;移动端&#xff09; android 仿微信demo————注册功能实现&#xff08;服务端&#xff09; android 仿微信demo————登录功能实现&#xff08;移动端&#xff09; an…

微信支付APIv3

文章目录 微信支付之前我的密钥啥的都是放到配置文件里面以后可以再写一个文件基础支付APIv3介绍获取验签和HttpClientAPIv3证书与密钥使用说明 微信支付的SDK工具Native支付流程我们程序运行时的日志也可以使用log.debug在方法堆栈里面查看我们程序执行的方法调用顺序内网穿透…

在线支付系列【8】微信支付之注册商户号

有道无术&#xff0c;术尚可求&#xff0c;有术无道&#xff0c;止于术。 文章目录 前言注册商户号1. 微信扫码登录2. 创建申请单2.1 基本信息2.2 主体身份2.3 法人信息及受益人信息2.4 经营与行业信息2.5 结算账户2.6 补充信息2.7 查看申请单 签约方式一&#xff1a;手机签约方…

Scala函数

1.基本语法 解析main方法 def main(args: Array[String]): Unit {函数体}*def 关键字&#xff0c;声明一个函数 * main 方法名 * args 参数名称 * Array[String] 参数的类型 * Unit 返回值类型&#xff0c;相当于Java中的void&#xff0c;没有返回值 * {} 函数体函数省略规则 …

微信公众号注册时提示该主体注册数量已超过上限怎么办?

很多用户在注册或认证微信公众号时&#xff0c;遇到“该主体注册数量已超过上限”的问题&#xff0c;这是怎么回事呢&#xff1f; 原因是2018年11月16日微信官方对公众号注册数量做了调整&#xff1a; 1.个人主体注册公众号数量上限由2个调整为1个&#xff1b; 2.企业类主体注…

开通微信公众号流程所需资料及时间

2019独角兽企业重金招聘Python工程师标准>>> 序号 阶段 所需资料 所需时间 一、&#xff08;企业&#xff09;注册公众平台 使用未注册过微信公众号的邮箱注册、验证激活 即时二、 选择帐号类型 详情查看服务号、订阅号、企业号区别后选择类型 即时三、信息登记 选择…

支付宝、微信注册时间,轻松查看!

早几天分享过与微信年度报告查询微信使用多少天&#xff0c;朋友圈传播非常火爆&#xff0c;今天教大家一招如何查询支付宝使用多少天。 看到上图还能回想到当时的激动吗&#xff1f; 马上进入正题&#xff0c;不啰嗦&#xff0c;查看支付宝注册日期的方法&#xff0c;也超级简…

车载ECU休眠唤醒-TJA1145

前言 首先&#xff0c;请教大家几个小小问题&#xff0c;你清楚&#xff1a; 什么是TJA1145吗&#xff1f;你知道休眠唤醒控制基本逻辑是怎么样的吗&#xff1f;TJA1145又是如何控制ECU进行休眠唤醒的呢&#xff1f;使用TJA1145时有哪些注意事项呢&#xff1f; 今天&#xff…

oppor15x支持html吗,oppor15x配置参数详情 r15和17的亲儿子

oppor15x虽然看上去和oppor15这款手机比较相似&#xff0c;但是实际上&#xff0c;作为oppo的最新款手机&#xff0c;oppor15x的发布时间是在oppor17之后的&#xff0c;不仅如此&#xff0c;在外观方面&#xff0c;oppor15x和oppor17会更为相似&#xff0c;在配置方面却更偏向o…

oppo r15 android 8,OPPO R15体验:基于安卓8.1,ColorOS 5.0更好用

当目前智能手机硬件性能普遍过剩&#xff0c;越来越多的人们开始逐渐意识到&#xff0c;参数并不等于体验&#xff0c;反而是依附于硬件之上的操作系统很大程度上直接决定了一款智能手机的使用体验。 在当前智能手机市场&#xff0c;虽然说安卓系统占据了绝大部分市场份额&…

android 汇编 参数,安卓ARM汇编基础知识

ARM 是 Advanced RISC Machine 的缩写&#xff0c;可以理解为一种处理器的架构&#xff0c;还可以将它作为一套完整的处理器指令集。RISC(Reduced Instruction Set Computing) 精简指令集计算机&#xff1a;一种执行较少类型计算机指令的微处理器。 处理器指令集: 计算机处理命…

linux x64 寄存器 传参,Linux X86架构参数传递规则

背景 突然好奇x86架构下函数参数怎么传递的,之前只是听别人说过通过寄存器,但是怎么传,什么顺序都没有仔细研究过,也没有实际测试过,因此就想着用实践来检验一下咯。 传参顺序 在32位和64位机器上,寄存器名称不同,64位机器为rxx,32位机器为exx。传参顺序如下, 64位系统…

linux控制协程参数,Linux高性能网络:协程系列06-协程实现之切换-Go语言中文社区...

目录 6.协程实现之切换 问题&#xff1a;协程的上下文如何切换&#xff1f;切换代码如何实现&#xff1f; 首先来回顾一下x86_64寄存器的相关知识。x86_64 的寄存器有16个64位寄存器&#xff0c;分别是&#xff1a;%rax, %rbx, %rcx, %esi, %edi, %rbp, %rsp, %r8, %r9, %r10, …

陶瓷气体放电管参数含义详解

​很多客户反应&#xff0c;不太明白陶瓷气体放电管产品手册中的参数含义。不可否认&#xff0c;电路保护器件产品规格书手册用的语言大部分都是英文&#xff0c;没有一定的英文基础&#xff0c;还真消化不了。有时候&#xff0c;就算能看得懂&#xff0c;但是面对枯燥无味的参…

ARM寄存器及功能介绍/R0-R15寄存器

1、ARM 寄存器组介绍 ARM 处理器一般共有 37 个寄存器&#xff0c;其中包括&#xff1a; &#xff08;1&#xff09; 31 个通用寄存器&#xff0c;包括 PC&#xff08;程序计数器&#xff09;在内&#xff0c;都是 32 位的寄存器。 &#xff08;2&#xff09; 6 个状态寄存器…

x64 汇编 参数传递

参数传递在不同的系统上是不一样的 称作 calling convention 调用约定 windows rcx,rdx,r8,r9 用来存储整数或指针参数&#xff0c;按照从左到右的顺序 xmm0,1,2,3 用来存储浮点参数 其余参数会压入栈中。 linux 当参数在 6 个以内&#xff0c;参数从左到右依次放入寄存器:…

汇编和c语言函数的参数,C函数与汇编函数之间参数及返回值传递方法

AAPCS对ARM结构的一些标准做了定义,在这里我们只重点介绍函数调用部分,如图8所示,AAPCS为ARM的R0~R15寄存器做了定义,明确了它们在函数中的职责: 图 8 AAPCS关于ARM寄存器的定义 一、函数调用时的规则如下: 1、 父函数与子函数间的入口参数依次通过R0~R3这4个寄存器传递。…

台式计算机配置参数,整机配置参数以及性能测试_台式电脑评测-中关村在线

我们首先来看一看同方E500的硬件配置情况。 根据AIDA64所示,同方E500搭载了i5-7400处理器、8GB内存、128GB建兴固态硬盘以及1TB西部数据机械硬盘。这个配置对于商务办公机来讲是非常合理的,在性能与成本之间得到了最佳的平衡。那么具体性能表现又是如何呢?我们来继续往下看。…

此计算机核心参数,买电脑如何选CPU?这三个参数一定要看!

原标题&#xff1a;买电脑如何选CPU&#xff1f;这三个参数一定要看! CPU是电脑中的核心&#xff0c;也可以说是电脑的大脑&#xff0c;一直以来CPU与GPU那个重要都是争论不休的话题&#xff0c;四月份升级九代酷睿处理器的机械师笔记本拥有怎样的升级体验呢?高性能玩家该通过…