WxJava开发微信登录、微信支付

WxJava开发微信支付、微信登录

  • 前言
  • 一、引入依赖
  • 二、修改配置文件
  • 三、小程序微信登录
    • 1.登录流程时序
    • 2.认识openid、unionid和code
    • 3.代码实现
  • 四、小程序微信支付
    • 1.业务流程图
    • 2.签名、私钥、证书、敏感信息加解密说明
    • 3.代码实现


前言

WxJava是微信Java开发工具包,支持包括微信支付、开放平台、公众号、企业微信/企业号、小程序等微信功能模块的后端开发。

名称网站
Gitee官网https://gitee.com/binary/weixin-java-tools
WxJava在线文档http://wxjava.fly2you.cn/zh-CN/start/pay/explain.html
开发文档Wikihttps://github.com/wechat-group/WxJava/wiki
Javadocweixin-java-miniapp 、weixin-java-pay、weixin-java-mp、weixin-java-common、weixin-java-cp、weixin-java-open
微信支付文档https://pay.weixin.qq.com/docs/merchant/apis/mini-program-payment/mini-prepay.html
微信登录文档https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/user-login/code2Session.html

准备工作
微信支付需要开通微信支付商户具体需要什么查看官网:https://pay.weixin.qq.com/docs/merchant/products/jsapi-payment/preparation.html

一、引入依赖

我这里使用的版本是4.5.0

<dependency><groupId>com.github.binarywang</groupId><artifactId>weixin-java-pay</artifactId><version>${weixin-java.version}</version>
</dependency>
<dependency><groupId>com.github.binarywang</groupId><artifactId>weixin-java-miniapp</artifactId><version>${weixin-java.version}</version>
</dependency>

二、修改配置文件

此处配置信息已经更改过不能直接使用
微信支付采用的是apiV3版本
证书路径可以是绝对路径也可以是classpath,我放到的项目的/resource/cert下

wx:miniapp:configs:- appid: wx2xxxxxxxxsecret: f7bd3ed88cxxxxxxx222e1a7e4f722ad9msgDataFormat: JSONpay:appId: wx2d0f68xxx7f #微信公众号或者小程序等的appidmchId: 1650000080 #微信支付商户号apiV3Key: TWBQNkNwwjxxxxx2hN5oQcertSerialNo: 2078791B21788DC90E44xxxxxx7291FFDprivateKeyPath: classpath:cert/apiclient_key.pem #apiclient_key.pem证书文件的绝对路径或者以classpath:开头的类路径privateCertPath: classpath:cert/apiclient_cert.pem #apiclient_cert.pem证书文件的绝对路径或者以classpath:开头的类路径notifyUrl: https://35fxxxxxpbf.guyubao.com/anonymous/wx/notify/order

三、小程序微信登录

1.登录流程时序

在这里插入图片描述

2.认识openid、unionid和code

1.openid

openid是用来唯一标识用户的一个字符串。在微信小程序中,每个用户的openid都是唯一的。通过openid,小程序可以获取用户的基本信息,如头像、昵称等。

注意:同一个用户在不同的小程序中拥有不同的openid。因此,在开发小程序时,不能使用openid来进行用户的唯一性判断。

2.unionid

unionid是在用户绑定同一微信开放平台账号下的多个应用时,用来唯一标识用户的一个字符串。如果用户在多个小程序中使用同一个微信号进行登录授权,那么这些小程序中的unionid都是相同的。

注意:用户的unionid只有在用户将多个应用绑定到同一个微信开放平台账号下时才会生成。因此,如果用户没有绑定多个应用,那么小程序将无法获取用户的unionid。

3. code

code是用户登录凭证,由微信服务器颁发给小程序。在用户授权登录后,小程序可以通过调用微信登录接口获取用户的code。然后,通过code向微信服务器请求用户的openid和session_key等信息。

注意:每个code只能使用一次,且有效期为5分钟。因此,在使用code进行登录时,需要及时将其转换成用户的openid和session_key等信息,以免出现code过期的情况

3.代码实现

1.在config目录下新增文件WxMaProperties

package com.ruoyi.xyhj.config;import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;import java.util.List;/*** @author <a href="https://github.com/binarywang">Binary Wang</a>*/
@Data
@ConfigurationProperties(prefix = "wx.miniapp")
public class WxMaProperties {private List<Config> configs;@Datapublic static class Config {/*** 设置微信小程序的appid*/private String appid;/*** 设置微信小程序的Secret*/private String secret;/*** 设置微信小程序消息服务器配置的token*/private String token;/*** 设置微信小程序消息服务器配置的EncodingAESKey*/private String aesKey;/*** 消息格式,XML或者JSON*/private String msgDataFormat;}}

2.注入wxMaService

package com.ruoyi.xyhj.config;import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.api.impl.WxMaServiceImpl;
import cn.binarywang.wx.miniapp.bean.WxMaKefuMessage;
import cn.binarywang.wx.miniapp.bean.WxMaSubscribeMessage;
import cn.binarywang.wx.miniapp.config.impl.WxMaDefaultConfigImpl;
import cn.binarywang.wx.miniapp.message.WxMaMessageHandler;
import cn.binarywang.wx.miniapp.message.WxMaMessageRouter;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.bean.result.WxMediaUploadResult;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.common.error.WxRuntimeException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import java.io.File;
import java.util.List;
import java.util.stream.Collectors;/*** @author <a href="https://github.com/binarywang">Binary Wang</a>*/
@Slf4j
@Configuration
@EnableConfigurationProperties(WxMaProperties.class)
public class WxMaConfiguration {private final WxMaProperties properties;@Autowiredpublic WxMaConfiguration(WxMaProperties properties) {this.properties = properties;}@Bean("wxMaService")public WxMaService wxMaService() {List<WxMaProperties.Config> configs = this.properties.getConfigs();if (configs == null) {throw new WxRuntimeException("大哥,拜托先看下项目首页的说明(readme文件),添加下相关配置,注意别配错了!");}WxMaService maService = new WxMaServiceImpl();maService.setMultiConfigs(configs.stream().map(a -> {WxMaDefaultConfigImpl config = new WxMaDefaultConfigImpl();
//                WxMaDefaultConfigImpl config = new WxMaRedisConfigImpl(new JedisPool());// 使用上面的配置时,需要同时引入jedis-lock的依赖,否则会报类无法找到的异常config.setAppid(a.getAppid());config.setSecret(a.getSecret());config.setToken(a.getToken());config.setAesKey(a.getAesKey());config.setMsgDataFormat(a.getMsgDataFormat());return config;}).collect(Collectors.toMap(WxMaDefaultConfigImpl::getAppid, a -> a, (o, n) -> o)));return maService;}@Beanpublic WxMaMessageRouter wxMaMessageRouter(WxMaService wxMaService) {final WxMaMessageRouter router = new WxMaMessageRouter(wxMaService);router.rule().handler(logHandler).next().rule().async(false).content("订阅消息").handler(subscribeMsgHandler).end().rule().async(false).content("文本").handler(textHandler).end().rule().async(false).content("图片").handler(picHandler).end().rule().async(false).content("二维码").handler(qrcodeHandler).end();return router;}private final WxMaMessageHandler subscribeMsgHandler = (wxMessage, context, service, sessionManager) -> {service.getMsgService().sendSubscribeMsg(WxMaSubscribeMessage.builder().templateId("此处更换为自己的模板id").data(Lists.newArrayList(new WxMaSubscribeMessage.MsgData("keyword1", "339208499"))).toUser(wxMessage.getFromUser()).build());return null;};private final WxMaMessageHandler logHandler = (wxMessage, context, service, sessionManager) -> {log.info("收到消息:" + wxMessage.toString());service.getMsgService().sendKefuMsg(WxMaKefuMessage.newTextBuilder().content("收到信息为:" + wxMessage.toJson()).toUser(wxMessage.getFromUser()).build());return null;};private final WxMaMessageHandler textHandler = (wxMessage, context, service, sessionManager) -> {service.getMsgService().sendKefuMsg(WxMaKefuMessage.newTextBuilder().content("回复文本消息").toUser(wxMessage.getFromUser()).build());return null;};private final WxMaMessageHandler picHandler = (wxMessage, context, service, sessionManager) -> {try {WxMediaUploadResult uploadResult = service.getMediaService().uploadMedia("image", "png",ClassLoader.getSystemResourceAsStream("tmp.png"));service.getMsgService().sendKefuMsg(WxMaKefuMessage.newImageBuilder().mediaId(uploadResult.getMediaId()).toUser(wxMessage.getFromUser()).build());} catch (WxErrorException e) {e.printStackTrace();}return null;};private final WxMaMessageHandler qrcodeHandler = (wxMessage, context, service, sessionManager) -> {try {final File file = service.getQrcodeService().createQrcode("123", 430);WxMediaUploadResult uploadResult = service.getMediaService().uploadMedia("image", file);service.getMsgService().sendKefuMsg(WxMaKefuMessage.newImageBuilder().mediaId(uploadResult.getMediaId()).toUser(wxMessage.getFromUser()).build());} catch (WxErrorException e) {e.printStackTrace();}return null;};}

3.调用

	@Resourceprivate WxMaService wxMaService;public String wxLoginOrRegister(String code) {if (StringUtils.isBlank(code)) {return "empty jscode";}try {//根据code获取openidWxMaJscode2SessionResult session = wxMaService.getUserService().getSessionInfo(code);} catch (WxErrorException e) {throw new WxLoginException(e.getMessage());}finally {WxMaConfigHolder.remove();//清理ThreadLocal}}

更多请参考官方示例:https://github.com/binarywang/weixin-java-miniapp-demo或javadoc

四、小程序微信支付

1.业务流程图

在这里插入图片描述

2.签名、私钥、证书、敏感信息加解密说明

1.签名格式
我们希望商户的技术开发人员按照当前文档约定的规则构造签名串。微信支付会使用同样的方式构造签名串。如果商户构造签名串的方式错误,将导致签名验证不通过。下面先说明签名串的具体格式。

签名串一共有五行,每一行为一个参数。结尾以\n(换行符,ASCII编码值为0x0A)结束,包括最后一行。如果参数本身以\n结束,也需要附加一个\n。

HTTP请求方法\n
URL\n
请求时间戳\n
请求随机串\n
请求报文主体\n

文档地址:
https://pay.weixin.qq.com/docs/merchant/development/interface-rules/signature-generation.html

2.私钥
商户申请商户 API 证书时,证书工具会生成商户私钥,并保存在本地证书文件夹的文件 apiclient_key.pem 中。私钥也可通过工具从商户的 p12 证书中导出。请妥善保管好商户私钥文件。
文档地址:
https://pay.weixin.qq.com/docs/merchant/development/interface-rules/privatekey-and-certificate.html

3.证书
商户API证书是指由商户申请的,包含商户的商户号、公司名称、公钥信息的证书。

微信支付 APIv3 使用由 证书授权机构(Certificate Authority,简称CA)签发的证书。商户可以自行生成证书请求串,也可以下载微信支付证书工具生成证书请求串。提交证书请求串至商户平台后,即可获得商户 API 证书文件。请注意安全保存私钥文件。

每个微信支付平台证书的有效期为5年。在证书过期之前,微信支付将逐步使用新的平台证书生成签名。为了避免缺少对应证书而验签失败,商户系统需支持多个微信支付平台证书,定期通过接口下载新证书并部署至服务器。请参阅我们的 证书更新指引 ,避免依赖人工更新证书,保证业务的连续运转。

文档地址:
https://pay.weixin.qq.com/docs/merchant/development/interface-rules/privatekey-and-certificate.html

4.加解密
为了保证通信过程中敏感信息字段(如用户的住址、银行卡号、手机号码等)的机密性,微信支付API v3要求商户对上送的敏感信息字段进行加密。与之相对应,微信支付会对下行的敏感信息字段进行加密,商户需解密后方能得到原文。下面详细介绍加解密的方式,以及如何进行相应的计算。

文档地址:
https://pay.weixin.qq.com/docs/merchant/development/interface-rules/sensitive-data-encryption.html

3.代码实现

1.在config目录下新增文件WxPayProperties

package com.ruoyi.xyhj.config;import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;/*** wxpay pay properties.** @author Binary Wang*/
@Data
@ConfigurationProperties(prefix = "wx.pay")
public class WxPayProperties {/*** 设置微信公众号或者小程序等的appid*/private String appId;/*** 微信支付商户号*/private String mchId;/*** 微信支付商户V3密钥*/private String apiV3Key;/*** 证书号*/private String certSerialNo;/*** apiclient_key.pem证书文件的绝对路径或者以classpath:开头的类路径*/private String privateKeyPath;/*** apiclient_cert.pem证书文件的绝对路径或者以classpath:开头的类路径*/private String privateCertPath;/*** 回调地址*/private String notifyUrl;}

2.注入WxPayService

package com.ruoyi.xyhj.config;import com.github.binarywang.wxpay.config.WxPayConfig;
import com.github.binarywang.wxpay.service.WxPayService;
import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
import lombok.AllArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;/*** @author Binary Wang*/
@Configuration
@ConditionalOnClass(WxPayService.class)
@EnableConfigurationProperties(WxPayProperties.class)
@AllArgsConstructor
public class WxPayConfiguration {private WxPayProperties properties;@Bean("wxPayService")@ConditionalOnMissingBeanpublic WxPayService wxService() {WxPayConfig payConfig = new WxPayConfig();payConfig.setAppId(StringUtils.trimToNull(this.properties.getAppId()));payConfig.setMchId(StringUtils.trimToNull(this.properties.getMchId()));payConfig.setApiV3Key(StringUtils.trimToNull(this.properties.getApiV3Key()));payConfig.setCertSerialNo(StringUtils.trimToNull(this.properties.getCertSerialNo()));payConfig.setPrivateKeyPath(StringUtils.trimToNull(this.properties.getPrivateKeyPath()));payConfig.setPrivateCertPath(StringUtils.trimToNull(this.properties.getPrivateCertPath()));payConfig.setNotifyUrl(StringUtils.trimToNull(this.properties.getNotifyUrl()));payConfig.setTradeType("JSAPI");payConfig.setSignType("MD5");WxPayService wxPayService = new WxPayServiceImpl();wxPayService.setConfig(payConfig);return wxPayService;}}

3.创建预支付订单

注意我们使用的是v3版本所以创建对象或者调用wxpayService时需要调用v3版本的不然参数可能对不上

/**
* 创建预支付订单
*/@Override@Transactionalpublic WxUnifiedOrderVo createOrder(PatriarchCreateOrderBo bo) throws WxPayException, IOException, SignatureException, NoSuchAlgorithmException, InvalidKeyException {//构建预支付订单对象WxPayUnifiedOrderV3Request orderV3Request = buildWxPayUnifiedOrderRequest(order, parentUser.getOpenid(), product.getName());WxPayUnifiedOrderV3Result wxPayUnifiedOrderV3Result = wxPayService.unifiedOrderV3(TradeTypeEnum.JSAPI, orderV3Request);//构建返回参数WxUnifiedOrderVo tokenJSAPI = WechatSignUtil.getTokenJSAPI(wxPayProperties.getAppId(), wxPayUnifiedOrderV3Result.getPrepayId(), wxPayProperties.getPrivateKeyPath());return tokenJSAPI;}
/*** 构建统一下单对象* @param order 订单对象* @param openId user openId* @param productName 产品名* @return*/public WxPayUnifiedOrderV3Request buildWxPayUnifiedOrderRequest(TelOrder order, String openId,String productName){WxPayUnifiedOrderV3Request orderRequest = new WxPayUnifiedOrderV3Request();//设置订单号orderRequest.setOutTradeNo(order.getId().toString());//设置交易结束时间为24小时orderRequest.setTimeExpire(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX").format(new Date()));//设置订单金额orderRequest.setAmount(new WxPayUnifiedOrderV3Request.Amount().setTotal(BaseWxPayRequest.yuanToFen(order.getAmount().toString())));//设置支付者信息orderRequest.setPayer(new WxPayUnifiedOrderV3Request.Payer().setOpenid(openId));//设置商品描述orderRequest.setDescription(productName);return orderRequest;}

4.签名工具类

package com.ruoyi.xyhj.utils;import com.ruoyi.xyhj.domain.vo.WxUnifiedOrderVo;import java.io.IOException;
import java.io.InputStream;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.HashMap;
import java.util.UUID;public class WechatSignUtil {/*** 参考网站 https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_5_4.shtml* 计算签名值** @param appId* @param prepay_id* @return* @throws IOException* @throws SignatureException* @throws NoSuchAlgorithmException* @throws InvalidKeyException*/public static WxUnifiedOrderVo getTokenJSAPI(String appId, String prepay_id, String privateKey) throws IOException, SignatureException, NoSuchAlgorithmException, InvalidKeyException {// 获取随机字符串String nonceStr = getNonceStr();// 获取微信小程序支付packageString packagestr = "prepay_id=" + prepay_id;long timestamp = System.currentTimeMillis() / 1000;//签名,使用字段appId、timeStamp、nonceStr、package计算得出的签名值String message = buildMessageTwo(appId, timestamp, nonceStr, packagestr);//获取对应的签名String signature = sign(message.getBytes("utf-8"),privateKey);// 组装返回WxUnifiedOrderVo vo = new WxUnifiedOrderVo();vo.setAppId(appId);vo.setTimeStamp(String.valueOf(timestamp));vo.setNonceStr(nonceStr);vo.setPackageStr(packagestr);vo.setSignType("RSA");vo.setPaySign(signature);return vo;}/*** 生成随机数* @return*/public static String getNonceStr(){return UUID.randomUUID().toString().replaceAll("-", "").substring(0, 32);}/*** 拼接参数** @return*/public static String buildMessageTwo(String appId, long timestamp, String nonceStr, String packag) {return appId + "\n"+ timestamp + "\n"+ nonceStr + "\n"+ packag + "\n";}/*** 生成签名** @return*/public static String sign(byte[] message,String privateKey) throws NoSuchAlgorithmException, SignatureException, IOException, InvalidKeyException {Signature sign = Signature.getInstance("SHA256withRSA"); //SHA256withRSAsign.initSign(getPrivateKey(privateKey));sign.update(message);return Base64.getEncoder().encodeToString(sign.sign());}/*** 获取私钥* @param filename 私钥文件路径  (required)* @return 私钥对象*/public static PrivateKey getPrivateKey(String filename) throws IOException {System.out.println("filename:" + filename);filename = filename.replace("classpath:", "");WechatSignUtil wechatSignUtil = new WechatSignUtil();InputStream resourceAsStream = wechatSignUtil.getClass().getClassLoader().getResourceAsStream(filename);byte[] bytes = new byte[0];bytes = new byte[resourceAsStream.available()];resourceAsStream.read(bytes);String content = new String(bytes);
//        String content = new String(Files.readAllBytes(Paths.get(resource.getPath())), "utf-8");try {String privateKey = content.replace("-----BEGIN PRIVATE KEY-----", "").replace("-----END PRIVATE KEY-----", "").replaceAll("\\s+", "");KeyFactory kf = KeyFactory.getInstance("RSA");return kf.generatePrivate(new PKCS8EncodedKeySpec(Base64.getDecoder().decode(privateKey)));} catch (NoSuchAlgorithmException e) {throw new RuntimeException("当前Java环境不支持RSA", e);} catch (InvalidKeySpecException e) {throw new RuntimeException("无效的密钥格式");}}
}

5.回调接口

 @ApiOperation(value = "支付回调通知处理")@PostMapping("/wx/notify/order")public void parseOrderNotifyResult(@RequestBody String resultData) throws WxPayException {WxPayOrderNotifyV3Result notifyV3Result = wxPayService.parseOrderNotifyV3Result(resultData,null);log.info("回调:{}",notifyV3Result.getResult());orderService.wxNotify(notifyV3Result.getResult());}

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【HTML专栏4】常用标签(标题、段落、换行、文本格式化、注释及特殊字符)

本文属于HTML/CSS专栏文章&#xff0c;适合WEB前端开发入门学习&#xff0c;详细介绍HTML/CSS如果使用&#xff0c;如果对你有所帮助请一键三连支持&#xff0c;对博主系列文章感兴趣点击下方专栏了解详细。 博客主页&#xff1a;Duck Bro 博客主页系列专栏&#xff1a;HTML/CS…

人脸签到系统 pyQT+数据库+深度学习

一、简介 人脸签到系统是一种基于人脸识别技术的自动签到和认证系统。它利用计算机视觉和深度学习算法来检测、识别和验证个体的面部特征&#xff0c;以确定其身份并记录其出现的时间。这个系统通常用于各种场景&#xff0c;包括企业、学校、会议、活动和公共交通等&#xff0c…

10个值得收藏的3D任务角色下载网站

每个人都喜欢免费的东西。 无论是免费的 3D 角色还是游戏资产&#xff0c;我们都喜欢它们。 以下是可以为你的游戏获取免费 3D 角色的前 10 个网站的列表。 你可以将它们用于多种用途&#xff0c;例如 3D 打印或动画剪辑。 如果需要将下载的3D模型转换为其他格式&#xff0c;可…

学生信息系统(python实现)

#codingutf-8 import os.path filenamestudent.txtdef menm():#菜单界面print(学生管理系统)print(-----------------------------功能菜单-----------------------------)print(\t\t\t\t\t\t1.录入学生信息)print(\t\t\t\t\t\t2.查找学生信息)print(\t\t\t\t\t\t3.删除学生信息…

超越代码行数!如何看待Python在大型项目中的真正价值?

在软件开发的世界里&#xff0c;Python是一门备受喜爱的编程语言&#xff0c;它以其简洁、易读和强大的特性而闻名。然而&#xff0c;就像所有备受关注的事物一样&#xff0c;Python也有其争议性话题。其中之一是关于Python在大型项目中的表现。有些人认为Python并不适合处理大…

探索珠宝商城小程序:商家如何实现线上卖珠宝

近期&#xff0c;微信小程序的发展势头强劲&#xff0c;各行各业都在积极开发自己的小程序&#xff0c;以适应这个数字化的时代。珠宝行业也不例外&#xff0c;许多珠宝品牌都已经推出了自己的小程序&#xff0c;为用户提供了更加便捷、个性化的购物体验。因此&#xff0c;制作…

K8s 多集群实践思考和探索

作者&#xff1a;vivo 互联网容器团队 - Zhang Rong 本文主要讲述了一些对于K8s多集群管理的思考&#xff0c;包括为什么需要多集群、多集群的优势以及现有的一些基于Kubernetes衍生出的多集群管理架构实践。 一、为什么需要多集群 随着K8s和云原生技术的快速发展&#xff0c…

error:03000086:digital envelope routines::initialization error

项目背景 前端vue项目启动突然报错error:03000086:digital envelope routines::initialization error 我用的开发工具是vscode&#xff0c;node版本是v18.17.0 前端项目版本如下↓ 具体报错如下↓ 报错原因 node版本过高 解决方法 1输入命令 $env:NODE_OPTIONS"--op…

安卓绘制原理之 MeasureCache优化了什么?

安卓绘制原理概览_油炸板蓝根的博客-CSDN博客 搜了一下&#xff0c;全网居然没有人提过 measureCache。 在前文中提到过&#xff0c;measure的时候&#xff0c;如果命中了 measureCache&#xff0c;会跳过 onMeasure&#xff0c;同时会设置 PFLAG3_MEASURE_NEEDED_BEFORE_LAYOU…

腾讯云centos7.6安装部署备忘

1.Mysql 1.1 安装mysql wget http://dev.mysql.com/get/mysql-community-release-el7-5.noarch.rpm rpm -ivh mysql-community-release-el7-5.noarch.rpm yum install mysql-community-server 1.1.1 安装后重启 service mysqld restart 1.1.2 初次安装mysql&#xff0c;root账…

c语言练习题52:写一个函数判断当前机器是大端还是小端

代码&#xff1a; #include<stdio.h> int check_sys() {int a 1;return *(char*)&a;//小端retrun 1 大端return 0&#xff1b; } int main() {if (check_sys() 1) {printf("小端\n");}elseprintf("大端\n"); } 这里首先取a的地址&#xff0c…

喜讯连连!疆程重磅发布全球独家3.6 TFT- LCD AR-HUD及CMS产品及解决方案,并斩获年度TOP10供应商

9月7日至8日&#xff0c;2023世界显示产业大会在成都盛大启幕&#xff0c;同期由BOE&#xff08;京东方&#xff09;承办的“Define the Future 智能座舱生态论坛”&#xff0c;合肥疆程技术有限公司创始人兼总经理康栋受邀出席并发布两款重磅座舱解决方案。 本次论坛以“智能座…

【css | loading】好看的loading特效

示例&#xff1a; https://code.juejin.cn/pen/7277764394618978365 html <div class"pl"><div class"pl__dot"></div><div class"pl__dot"></div><div class"pl__dot"></div><div c…

前端面试经典题--页面布局

题目 假设高度已知&#xff0c;请写出三栏布局&#xff0c;其中左、右栏宽度各为300px&#xff0c;中间自适应。 五种解决方式代码 浮动解决方式 绝对定位解决方式 flexbox解决方式 表格布局 网格布局 源代码 <!DOCTYPE html> <html lang"en"> <…

数据结构算法-分而治之算法

引言 在茫茫人海中找寻那个特定的身影&#xff0c;犹如在浩瀚的星海中寻找那一颗独特的星辰。小森&#xff0c;一个平凡而真实的男孩&#xff0c;此时正在人群中寻找他的朋友&#xff0c;温迪。 小森运用了一种“分而治之”的算法策略&#xff0c;将周围的人群分成两组&#…

c++day4

仿照string类&#xff0c;完成myString 类 #include <iostream> #include<cstring>using namespace std; class myString {private:char *str; //记录c风格的字符串int size; //记录字符串的实际长度public://无参构造myString():size(10){str…

mysql技术文档--之与redo log(重做日志)庖丁解析-超级探索!!!

阿丹&#xff1a; 在刚开始写本文章的是还不太清楚要如何去细啃下这两个体系&#xff0c;在查阅资料的过程中。发现大厂阿里的庖丁解InnoDB系列&#xff0c;详细了的写了很多底层知识&#xff0c;于是基于这个这两个文章才有了阿丹的这篇文章。 整体认知&#xff1a; 在 MySQ…

nVisual光纤资源管理软件,亮相第24届光博会

第24届中国国际光电博览会&#xff08;CIOE&#xff09;于9月6日至8日在深圳国际会展中心盛大开幕。作为行业领先的网络基础设施管理软件供应商&#xff0c;耐威迪携nVisual光纤资源管理软件亮相9号馆C001、C002展位&#xff0c;全方位展示室外网络基础设施管理、光纤资源管理、…

2022年全国研究生数学建模竞赛华为杯E题草原放牧策略研究求解全过程文档及程序

2022年全国研究生数学建模竞赛华为杯 E题 草原放牧策略研究 原题再现&#xff1a; 一、背景介绍   草原作为世界上分布最广的重要的陆地植被类型之一&#xff0c;分布面积广泛。中国的草原面积为3.55亿公顷&#xff0c;是世界草原总面积的6%~8%&#xff0c;居世界第二。此外…

CSP-J初赛复习大题整理笔记

本篇全是整理&#xff0c;为比赛准备. 在这里插入代码片 #include<cstdio> using namespace std; int n, m; int a[100], b[100];int main() {scanf_s("%d%d", &n, &m);for (int i 1; i < n; i)a[i] b[i] 0;//将两个数组清0&#xff0c;这…