当前位置: 首页 > news >正文

Java企业微信服务商代开发获取AccessToken示例

这里主要针对的是企业微信服务商代开发模式 文档地址

在这里插入图片描述

可以看到里面大致有三种token,一个是服务商的token,一个是企业授权token,还有一个是应用的token
这里面主要有下面几个参数
首先是服务商的 corpid 和 provider_secret ,这个可以在 应用管理-通用开发参数 里面查看

在这里插入图片描述

然后是企业的 corpid 和企业的永久授权码 permanent_code ,这两个是需要在企业授权的的时候通过回调获取的,具体请参考官方文档 获取永久授权码

最后就是应用的 suite_id 和 suite_secret 还需要一个 suite_ticket ,前面两个在应用信息里面就可以看到,suite_ticket 这个也是需要通过回调获取 ,具体参考官方文档 推送suite_ticket

在这里插入图片描述

拿到这些参数后就好说了,剩下的都是调接口
直接上代码

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.qyzj.common.base.exception.BusinessException;
import com.qyzj.common.base.util.HttpsRequestUtil;
import com.qyzj.common.redis.constant.CacheKey;
import com.qyzj.common.redis.util.RedisUtil;
import com.qyzj.service.task.constant.WeiXinProviderConst;
import com.qyzj.service.task.constant.WeixinCorpKeyConst;
import com.qyzj.service.task.constant.WeixinCorpUrlConst;
import lombok.extern.java.Log;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;/*** @author Sakura* @date 2024/7/2 11:48*/
@Component
@Log
public class WxTokenUtil {@Autowiredprivate RedisUtil redisUtil;// 获取服务商token// 这里有一个问题,企业微信本身可能会使token提前失效,所以有时需要强制重新获取token,详情见官方文档// https://developer.work.weixin.qq.com/document/path/91200// 所以此处加了一个cache用来判断是否需要走缓存拿token,正常情况默认走缓存即可public String getProviderAccessToken(Boolean cache) {try {// 如果Redis里面有则直接取Redis里面的if (cache &&redisUtil.hasKey(CacheKey.KEY_CORP_PROVIDER_ACCESS_TOKEN)) {return redisUtil.get(CacheKey.KEY_CORP_PROVIDER_ACCESS_TOKEN).toString();}// 封装请求参数JSONObject json = new JSONObject();json.put("corpid", WeiXinProviderConst.corpId);json.put("provider_secret", WeiXinProviderConst.providerSecret);// 请求微信接口String accessTokenStr = HttpsRequestUtil.sendPostRequest(WeixinCorpUrlConst.PROVIDER_ACCESS_TOKEN, json.toJSONString());log.info("get provider access token return :" + accessTokenStr);JSONObject accessTokenJson = JSON.parseObject(accessTokenStr);// 获取 access_tokenString accessToken = accessTokenJson.getString(WeixinCorpKeyConst.providerAccessToken);//官方 expires_in 为 2个小时, 这里设置100分钟redisUtil.set(CacheKey.KEY_CORP_PROVIDER_ACCESS_TOKEN, accessToken, CacheKey.expireTime100);return accessToken;} catch (Exception e) {log.info("get provider access token error");e.printStackTrace();throw new BusinessException("get provider access token error");}}// 获取企业授权tokenpublic String getCorpAccessToken(String corpId, String permanentCode) {try {// 如果Redis里面有则直接取Redis里面的if (redisUtil.hasKey(CacheKey.KEY_CORP_ACCESS_TOKEN + "_" + corpId)) {return redisUtil.get(CacheKey.KEY_CORP_ACCESS_TOKEN + "_" + corpId).toString();}String accessTokenUrl = WeixinCorpUrlConst.CORP_ACCESS_TOKEN.replace("#{CORP_ID}", corpId).replace("#{CORP_SECRET}", permanentCode);String accessTokenStr = HttpsRequestUtil.sendGetRequest(accessTokenUrl);log.info("get corp access token return :" + accessTokenStr);JSONObject accessTokenJson = JSON.parseObject(accessTokenStr);// 获取 access_tokenString accessToken = accessTokenJson.getString(WeixinCorpKeyConst.accessToken);//官方 expires_in 为 2个小时, 这里设置 100 分钟redisUtil.set(CacheKey.KEY_CORP_ACCESS_TOKEN + "_" + corpId, accessToken, CacheKey.expireTime100);return accessToken;} catch (Exception e) {log.info("get corp access token error");e.printStackTrace();throw new BusinessException("get corp access token error");}}// SuiteTicket是通过回调获取的,企微每10分钟会推送一次// 如果没有可手动在服务商企业微信后台刷新public String getSuiteTicket() {// 如果Redis里面有则直接取Redis里面的if (redisUtil.hasKey(CacheKey.KEY_CORP_SUITE_TICKET)) {return redisUtil.get(CacheKey.KEY_CORP_SUITE_TICKET).toString();} else {log.info("get suite ticket error");throw new BusinessException("get suite ticket error");}}// 获取应用token// 注意suiteTicket是从回调接口获取的// 注意该token需要配置ip白名单public String getSuiteAccessToken() {try {// 如果Redis里面有则直接取Redis里面的if (redisUtil.hasKey(CacheKey.KEY_SUITE_ACCESS_TOKEN)) {return redisUtil.get(CacheKey.KEY_SUITE_ACCESS_TOKEN).toString();}// 封装请求参数JSONObject json = new JSONObject();json.put(WeixinCorpKeyConst.suiteId, WeiXinProviderConst.suiteId);json.put(WeixinCorpKeyConst.suiteSecret, WeiXinProviderConst.suiteSecret);json.put(WeixinCorpKeyConst.suiteTicket, getSuiteTicket());String accessTokenStr = HttpsRequestUtil.sendPostRequest(WeixinCorpUrlConst.SUITE_ACCESS_TOKEN, json.toJSONString());log.info("get suite access token return :" + accessTokenStr);JSONObject accessTokenJson = JSON.parseObject(accessTokenStr);//获取 accessTokenString accessToken = accessTokenJson.getString(WeixinCorpKeyConst.suiteAccessToken);//官方 expires_in 为 2个小时, 这里设置 100分钟redisUtil.set(CacheKey.KEY_SUITE_ACCESS_TOKEN, accessToken, CacheKey.expireTime100);return accessToken;} catch (Exception e) {log.info("get suite access token error");e.printStackTrace();throw new BusinessException("get suite access token error");}}
}

这里面用到的 HttpsRequestUtil 工具类

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;/*** @author Sakura* @date 2024/6/24 17:07*/
public class HttpsRequestUtil {public static String sendPostRequest(String urlString, String jsonInputString) throws IOException {URL url = new URL(urlString);HttpURLConnection connection = (HttpURLConnection) url.openConnection();// 设置请求方法为POSTconnection.setRequestMethod("POST");// 设置请求头connection.setRequestProperty("Content-Type", "application/json");connection.setRequestProperty("Accept", "application/json");// 启用输出流,用于发送请求数据connection.setDoOutput(true);try (OutputStream os = connection.getOutputStream()) {byte[] input = jsonInputString.getBytes("utf-8");os.write(input, 0, input.length);}// 获取响应try (BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream(), "utf-8"))) {StringBuilder response = new StringBuilder();String responseLine;while ((responseLine = br.readLine()) != null) {response.append(responseLine.trim());}return response.toString();} finally {// 关闭连接connection.disconnect();}}public static String sendGetRequest(String urlString) throws IOException {URL url = new URL(urlString);HttpURLConnection connection = (HttpURLConnection) url.openConnection();// 设置请求方法为GETconnection.setRequestMethod("GET");// 设置请求头connection.setRequestProperty("Accept", "application/json");// 获取响应try (BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream(), "utf-8"))) {StringBuilder response = new StringBuilder();String responseLine;while ((responseLine = br.readLine()) != null) {response.append(responseLine.trim());}return response.toString();} finally {// 关闭连接connection.disconnect();}}}

还有企业微信的两个基本配置类

public class WeixinCorpUrlConst {/*** 获取 provider_access_token 的 url*/public static final String PROVIDER_ACCESS_TOKEN = "https://qyapi.weixin.qq.com/cgi-bin/service/get_provider_token";/*** 获取 suite_access_token 的 url*/public static final String SUITE_ACCESS_TOKEN = "https://qyapi.weixin.qq.com/cgi-bin/service/get_suite_token";/*** 获取 pre_auth_code 的 url*/public static final String PRE_AUTH_CODE = "https://qyapi.weixin.qq.com/cgi-bin/service/get_pre_auth_code?suite_access_token=";/*** 前端授权页面 的 url*/public static final String URL_AUTH_PAGE = "https://open.work.weixin.qq.com/3rdapp/install";/*** 前端登录页面 的 url*/public static final String URL_LOGIN_PAGE = "https://open.work.weixin.qq.com/wwopen/sso/3rd_qrConnect";/*** 获取 permanent_code 的 url*/public static final String PERMANENT_CODE = "https://qyapi.weixin.qq.com/cgi-bin/service/get_permanent_code?suite_access_token=";/*** 获取 企业授权 access_token 的 url*/public static final String CORP_ACCESS_TOKEN = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=#{CORP_ID}&corpsecret=#{CORP_SECRET}";/*** 获取 企业应用 access_token 的 url*/public static final String ACCESS_TOKEN = "https://qyapi.weixin.qq.com/cgi-bin/gettoken";/*** 获取 应用信息 的 url*/public static final String AGENT_INFO = "https://qyapi.weixin.qq.com/cgi-bin/agent/get?access_token=#{ACCESS_TOKEN}&agentid=#{AGENT_ID}";/*** 获取 部门列表 的 url*/public static final String DEPARTMENT_LIST = "https://qyapi.weixin.qq.com/cgi-bin/department/list?access_token=#{ACCESS_TOKEN}";/*** 获取 部门成员列表 的 url*/public static final String USER_LIST = "https://qyapi.weixin.qq.com/cgi-bin/user/list?access_token=#{ACCESS_TOKEN}&department_id=#{DEPARTMENT_ID}&fetch_child=1";/*** 获取 成员信息 的 url*/public static final String USER_INFO = "https://qyapi.weixin.qq.com/cgi-bin/user/get?access_token=#{ACCESS_TOKEN}&userid=#{USER_ID}";/*** 获取 企业管理员 的 url*/public static final String ADMIN_USER_LIST = "https://qyapi.weixin.qq.com/cgi-bin/service/get_admin_list?suite_access_token=";/*** 第三方应用:获取 企业成员登录信息 的 url*/public static final String PROVIDER_LOGIN_INFO = "https://qyapi.weixin.qq.com/cgi-bin/service/get_login_info?access_token=";/*** 自建应用:获取 企业成员登录信息 的 url*/public static final String LOCAL_LOGIN_INFO = "https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo?access_token=#{ACCESS_TOKEN}&code=#{CODE}";public static final String LOGIN_DETAIL_INFO = "https://qyapi.weixin.qq.com/cgi-bin/user/getuserdetail?access_token=#{ACCESS_TOKEN}";/*** 批量获取 客户列表 的 url*/public static final String BATCH_CUSTOMER_LIST = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/batch/get_by_user?access_token=#{ACCESS_TOKEN}";/*** 获取 客户详情 的 url*/public static final String CUSTOMER_INFO = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get?access_token=#{ACCESS_TOKEN}&external_userid=#{EXTERNAL_USERID}";/*** 修改 客户备注信息 的url*/public static final String UPDATE_CUSTOMER_REMARK = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/remark?access_token=#{ACCESS_TOKEN}";/*** 编辑 客户标签 的url*/public static final String MARK_CUSTOMER_TAG = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/mark_tag?access_token=#{ACCESS_TOKEN}";/*** 获取 企业标签 的 url*/public static final String TAG_GROUP_LIST = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get_corp_tag_list?access_token=";/*** 添加 企业标签 的 url*/public static final String ADD_TAG_GROUP = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/add_corp_tag?access_token=";/*** 修改 企业标签 的 url*/public static final String UPDATE_TAG_GROUP = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/edit_corp_tag?access_token=";/*** 删除 企业标签 的 url*/public static final String DELETE_TAG_GROUP = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/del_corp_tag?access_token=";/*** 获取 客户群列表 的 url*/public static final String GROUP_CHAT_LIST = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/groupchat/list?access_token=#{ACCESS_TOKEN}";/*** 获取 客户群详情 的 url*/public static final String GROUP_CHAT_INFO = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/groupchat/get?access_token=#{ACCESS_TOKEN}";/*** 查询 联系我 的 url*/public static final String GET_CONTACT_WAY = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get_contact_way?access_token=#{ACCESS_TOKEN}";/*** 添加 联系我 的 url*/public static final String ADD_CONTACT_WAY = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/add_contact_way?access_token=#{ACCESS_TOKEN}";/*** 更新 联系我 的 url*/public static final String UPDATE_CONTACT_WAY = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/update_contact_way?access_token=#{ACCESS_TOKEN}";/*** 删除 联系我 的 url*/public static final String DEL_CONTACT_WAY = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/del_contact_way?access_token=#{ACCESS_TOKEN}";/*** 发送 欢迎语  的 url*/public static final String SEND_WELCOME_MSG = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/send_welcome_msg?access_token=#{ACCESS_TOKEN}";/*** 上传 临时素材 的 url*/public static final String UPLOAD_MEDIA = "https://qyapi.weixin.qq.com/cgi-bin/media/upload?access_token=";/*** 添加 入群欢迎语素材  的 url*/public static final String ADD_GROUP_WELCOME_TEMPLATE = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/group_welcome_template/add?access_token=#{ACCESS_TOKEN}";/*** 更新 入群欢迎语素材  的 url*/public static final String UPDATE_GROUP_WELCOME_TEMPLATE = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/group_welcome_template/edit?access_token=#{ACCESS_TOKEN}";/*** 删除 入群欢迎语素材  的 url*/public static final String DEL_GROUP_WELCOME_TEMPLATE = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/group_welcome_template/del?access_token=#{ACCESS_TOKEN}";/*** 发送 应用消息  的 url*/public static final String SEND_APPLICATION_MESSAGE = "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=#{ACCESS_TOKEN}";/*** 获取待分配的离职成员列表 的url*/public static final String DIMISSION_WAIT_ALLOT_CLIENT = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get_unassigned_list?access_token=#{ACCESS_TOKEN}";/*** 分配离职成员的客户*/public static final String DIMISSION_ALLOT_Client = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/resigned/transfer_customer?access_token=#{ACCESS_TOKEN}";/***  分配离职成员的客户群*/public static final String DIMISSION_ALLOT_GROUP = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/groupchat/transfer?access_token=#{ACCESS_TOKEN}";/*** 创建企业群发*/public static final String ADD_CORP_MASS_URL = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/add_msg_template?access_token=#{ACCESS_TOKEN}";/*** 编辑客户企业标签*/public static final String EDIT_CUSTOMER_CORP_TAG = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/mark_tag?access_token=#{ACCESS_TOKEN}";/*** 获取企业的jsapi_ticket*/public static final String CORP_JS_API_TICKET = "https://qyapi.weixin.qq.com/cgi-bin/get_jsapi_ticket?access_token=";/*** 获取应用的jsapi_ticket*/public static final String AGENT_JS_API_TICKET = "https://qyapi.weixin.qq.com/cgi-bin/ticket/get?type=agent_config&access_token=";/*** 获取 开通了会话存档的员工*/public static final String MSG_AUDIT_EMPLOYEE = "https://qyapi.weixin.qq.com/cgi-bin/msgaudit/get_permit_user_list?access_token=#{ACCESS_TOKEN}";/*** corpid转换 的 url*/public static final String CORPID_TO_OPENCORPID = "https://qyapi.weixin.qq.com/cgi-bin/service/corpid_to_opencorpid?provider_access_token=";/*** userid转换 的 url*/public static final String USERID_TO_OPENUSERID = "https://qyapi.weixin.qq.com/cgi-bin/batch/userid_to_openuserid?access_token=";public static final String GET_NEW_EXTERNAL_USERID = "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get_new_external_userid?access_token=";public static final String UNIONID_TO_EXTERNAL_USERID = "https://qyapi.weixin.qq.com/cgi-bin/idconvert/unionid_to_external_userid?access_token=";public static final String EXTERNAL_USERID_TO_PENDING_ID = "https://qyapi.weixin.qq.com/cgi-bin/idconvert/batch/external_userid_to_pending_id?access_token=";public static final String FINISH_OPENID_MIGRATION = "https://qyapi.weixin.qq.com/cgi-bin/service/finish_openid_migration?provider_access_token=";
}
public class WeixinCorpKeyConst {public static String errcode = "errcode";public static String errmsg = "errmsg";// 服务商相关public static String corpId = "corpid";public static String authCorpId = "auth_corpid";public static String corpName = "corp_name";public static String suiteId = "suite_id";public static String suiteSecret = "suite_secret";public static String providerSecret = "provider_secret";public static String corpSecret = "corpsecret";public static String suiteTicket = "suite_ticket";public static String suiteAccessToken = "suite_access_token";public static String providerAccessToken = "provider_access_token";public static String preAuthCode = "pre_auth_code";public static String authCode = "auth_code";public static String permanentCode = "permanent_code";public static String authCorpInfo = "auth_corp_info";public static String authInfo = "auth_info";public static String agent = "agent";public static String agentId = "agentid";public static String accessToken = "access_token";}

WeiXinProviderConst 就不贴了,里面就是记录上面那几个参数的

到这里可以发现,其实对接企业微信并不难,麻烦的地方就在于各种配置各种参数,然后就是回调,回调这个后面有空我也会整理出来

相关文章:

Java企业微信服务商代开发获取AccessToken示例

这里主要针对的是企业微信服务商代开发模式 文档地址 可以看到里面大致有三种token,一个是服务商的token,一个是企业授权token,还有一个是应用的token 这里面主要有下面几个参数 首先是服务商的 corpid 和 provider_secret ,这个可…...

How does age change how you learn?(2)年龄如何影响学习能力?(二)

Do different people experience decline differently? 不同人经历的认知衰退会有不同吗? Do all people experience cognitive decline uniformly?Or do some people’s minds slip while others stay sharp much longer? 所有人经历的认知衰退都是一样的吗?还是有些人…...

可验证随机函数 vrf 概述

一、什么是VRF 背景: 在传统的区块链中,常用的随机算法是基于伪随机数生成器(Pseudorandom Number Generator,PRNG)的。PRNG是一种确定性算法,它根据一个初始种子生成一个看似随机的序列。在区块链中,通常使用的是伪随机数序列来选择区块的创建者、确定验证节点的轮换…...

鸿蒙双向绑定组件:TextArea、TextInput、Search、Checkbox,文本输入组件,图案解锁组件PatternLock

对象暂不支持双向绑定, 效果: 代码: Entry Component struct MvvmCase {StateisSelect: boolean falseStatesearchText: String ""StateinputText: string ""StateareaText: string ""build() {Grid() {G…...

JS 算法 - 计数器

theme: smartblue 题目描述 给定一个整型参数 n,请你编写并返回一个 counter 函数。这个 counter 函数最初返回 n,每次调用它时会返回前一个值加 1 的值 ( n , n 1 , n 2 ,等等)。 示例 1: 输入: n 10 ["cal…...

JavaScript基础——JavaScript运算符

赋值运算符 算术运算符 一元运算符 三元/三目运算符 比较运算符 逻辑运算符 运算符优先级 在JavaScript中,常见的运算符可以包括赋值运算符、一元运算符、算术运算符(二元运算符)、三元/三目运算符、比较运算符、逻辑运算符等&#xff0…...

E23.【C语言】练习:不创建第三个变量实现两个整数的交换

目录 题目条件 思路1( -) 思路2 (^)(XOR) 往期推荐 1.题目条件 禁止使用以上代码 2.思路1: -运算 aab; ba-b; aa-b; 但这样有潜在的问题 :a,b存储的数字过大,ab可能超过范围 因此改用思路2…...

如何搭建一个web系统?

需求 搭建一个web系统。 框架 设计:墨刀 前端:Vue.js 后端:Java 算法:Python 数据库:时序数据库,介绍 部署:Jekins https://www.jenkins.io/ 文档管理:Teambition 项目管理:禅道 代码管理:Gitlab 开发流程 设计文档和原型文档,功能接口设计&#xff0…...

三十种未授权访问漏洞复现 合集( 二 )

未授权访问漏洞介绍 未授权访问可以理解为需要安全配置或权限认证的地址、授权页面存在缺陷,导致其他用户可以直接访问,从而引发重要权限可被操作、数据库、网站目录等敏感信息泄露。---->目录遍历 目前主要存在未授权访问漏洞的有:NFS服务&a…...

C语言学习笔记[29]:函数①

函数 在C语言中,函数是一段可以完成特定功能的代码,它们可以被重复调用。 函数的分类: 库函数自定义函数 库函数 在C语言中,库函数是由系统提供的,用于完成特定功能的函数,这些函数被集合在一起&#…...

使用Springboot + netty 打造聊天服务之Nacos集群问题记录

目录 1、前言1.1、方法一1.2、方法二 2、方案二实战2.1、在netty服务里加上ws连接、中断事件2.2、在netty服务里加上消息服务 4、总结 使用Springboot netty 打造聊天服务系列文章 第一章 初始搭建工程 第二章 Nacos集群问题记录 1、前言 在使用Springboot Nacos Netty(Web…...

全网唯一!R语言顶刊配色包TheBestColors

与Matlab相比,R语言在绘图方面有着天然的优势。 比如在配色方面,R语言有各式各样现成的包,按理说配色这种事应该很方便才对。 但实际体验下来,发现似乎不是那么回事。 首先,你很难记住每个包的调用方法以及每种配色…...

链表题型思路错误总结

常见题目 206. 反转链表 关键点:定义前置指针。 在给cur.next复制前,需要定义好next节点防止断链。 public ListNode reverseList(ListNode head) {if (head null || head.next null) {return head;}ListNode pre null;ListNode cur head;while(cur…...

算法学习day28

一、寻找右区间(二分法) 题意:题目很容易理解 但是转换为二分法有点晦涩 给你一个区间数组 intervals ,其中 intervals[i] [starti, endi] ,且每个 starti 都 不同 。区间 i 的 右侧区间 可以记作区间 j ,并满足 startj > e…...

C语言基础题:迷宫寻路(C语言版)

1.题目描述 机器猫被困在一个矩形迷宫里。 迷宫可以视为一个n x m 矩阵,每个位置要么是空地,要么是墙。机器猫只能从一个空地走到其上、下、左、右的空地。 机器猫初始时位于(1,1)的位置,问能否走到(n,m)位置。 2.输入格式 第一行&#xff0…...

力扣-1两数之和2两数相加-2024/8/3

1、两数之和 解法一 暴力法(2个for循环) class Solution:def twoSum(self, nums: List[int], target: int) -> List[int]:for ii in range(len(nums)):for jj in range(ii1, len(nums)):if nums[ii]nums[jj] target:return [ii,jj]解法二 哈希表法…...

简站WordPress主题 专业的WordPress建站服务商

简站WordPress主题是一款备受推崇的WordPress主题,以其简洁、实用、无插件和更安全的特性脱颖而出。以下是关于简站WordPress主题的一些详细分析: 简站WordPress主题采用了扁平化设计风格,界面简洁明了,这使得网站看起来更加专业…...

Final Shell for Mac 虚拟机连接工具【简单易操作,轻松上手】【开发所需连接工具】

Mac分享吧 文章目录 效果一、下载软件二、安装软件三、运行测试安装完成!!! 效果 一、下载软件 下载软件 链接:http://www.macfxb.cn 二、安装软件 三、运行测试 安装完成!!!...

Oracle JDK:版本、支持与许可

文章目录 版本支持许可BCLOTNNFTCFAQ其他OpenJDK和其他的JDK实现JDK、JRE、JVMJava SE、Java EE、Java ME版本 Oracle JDK的最新版本和历史版本的官方下载地址(可查询版本发行说明等信息):https://www.oracle.com/cn/java/technologies/downloads/ 常规版本(非LTS):每隔…...

大模型学习笔记 - LLM 之RLHF人类对齐的简单总结

LLM - RLHF人类对齐的简单总结 LLM-人类对齐 1. RLHF(Reinforcement Learning from Human Feedback, RLHF),基于人类反馈的强化学习2 奖励模型训练3 强化学习训练 3.1 PPO介绍3.2 进阶的RLHF的介绍 3.2.1. 过程监督奖励模型3.2.2. 基于AI反馈的强化学习3.2.3. 非强化学习的对齐…...

React 第五十五节 Router 中 useAsyncError的使用详解

前言 useAsyncError 是 React Router v6.4 引入的一个钩子,用于处理异步操作(如数据加载)中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误:捕获在 loader 或 action 中发生的异步错误替…...

盘古信息PCB行业解决方案:以全域场景重构,激活智造新未来

一、破局:PCB行业的时代之问 在数字经济蓬勃发展的浪潮中,PCB(印制电路板)作为 “电子产品之母”,其重要性愈发凸显。随着 5G、人工智能等新兴技术的加速渗透,PCB行业面临着前所未有的挑战与机遇。产品迭代…...

React第五十七节 Router中RouterProvider使用详解及注意事项

前言 在 React Router v6.4 中&#xff0c;RouterProvider 是一个核心组件&#xff0c;用于提供基于数据路由&#xff08;data routers&#xff09;的新型路由方案。 它替代了传统的 <BrowserRouter>&#xff0c;支持更强大的数据加载和操作功能&#xff08;如 loader 和…...

PHP和Node.js哪个更爽?

先说结论&#xff0c;rust完胜。 php&#xff1a;laravel&#xff0c;swoole&#xff0c;webman&#xff0c;最开始在苏宁的时候写了几年php&#xff0c;当时觉得php真的是世界上最好的语言&#xff0c;因为当初活在舒适圈里&#xff0c;不愿意跳出来&#xff0c;就好比当初活在…...

通过Wrangler CLI在worker中创建数据库和表

官方使用文档&#xff1a;Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后&#xff0c;会在本地和远程创建数据库&#xff1a; npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库&#xff1a; 现在&#xff0c;您的Cloudfla…...

基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容

基于 ​UniApp + WebSocket​实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配​微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...

P3 QT项目----记事本(3.8)

3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...

Python爬虫(二):爬虫完整流程

爬虫完整流程详解&#xff08;7大核心步骤实战技巧&#xff09; 一、爬虫完整工作流程 以下是爬虫开发的完整流程&#xff0c;我将结合具体技术点和实战经验展开说明&#xff1a; 1. 目标分析与前期准备 网站技术分析&#xff1a; 使用浏览器开发者工具&#xff08;F12&…...

ServerTrust 并非唯一

NSURLAuthenticationMethodServerTrust 只是 authenticationMethod 的冰山一角 要理解 NSURLAuthenticationMethodServerTrust, 首先要明白它只是 authenticationMethod 的选项之一, 并非唯一 1 先厘清概念 点说明authenticationMethodURLAuthenticationChallenge.protectionS…...

力扣-35.搜索插入位置

题目描述 给定一个排序数组和一个目标值&#xff0c;在数组中找到目标值&#xff0c;并返回其索引。如果目标值不存在于数组中&#xff0c;返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 class Solution {public int searchInsert(int[] nums, …...