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

spring security + oauth2 使用RedisTokenStore 以json格式存储

1.项目架构

 2.自己对 TokenStore 的 redis实现

package com.enterprise.auth.config;import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.Cursor;
import org.springframework.data.redis.core.ScanOptions;
import org.springframework.security.oauth2.common.ExpiringOAuth2RefreshToken;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.common.OAuth2RefreshToken;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.token.AuthenticationKeyGenerator;
import org.springframework.security.oauth2.provider.token.DefaultAuthenticationKeyGenerator;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.redis.JdkSerializationStrategy;
import org.springframework.security.oauth2.provider.token.store.redis.RedisTokenStore;
import org.springframework.security.oauth2.provider.token.store.redis.RedisTokenStoreSerializationStrategy;
import org.springframework.util.ClassUtils;
import org.springframework.util.ReflectionUtils;import java.lang.reflect.Method;
import java.nio.charset.StandardCharsets;
import java.util.*;public class MyRedisTokenStore implements TokenStore {private static final String ACCESS = "access:";private static final String AUTH_TO_ACCESS = "auth_to_access:";private static final String AUTH = "auth:";private static final String REFRESH_AUTH = "refresh_auth:";private static final String ACCESS_TO_REFRESH = "access_to_refresh:";private static final String REFRESH = "refresh:";private static final String REFRESH_TO_ACCESS = "refresh_to_access:";private static final String CLIENT_ID_TO_ACCESS = "client_id_to_access:";private static final String UNAME_TO_ACCESS = "uname_to_access:";private static final boolean springDataRedis_2_0 = ClassUtils.isPresent("org.springframework.data.redis.connection.RedisStandaloneConfiguration", RedisTokenStore.class.getClassLoader());private final RedisConnectionFactory connectionFactory;private AuthenticationKeyGenerator authenticationKeyGenerator = new DefaultAuthenticationKeyGenerator();private RedisTokenStoreSerializationStrategy serializationStrategy = new MyRedisTokenStoreSerializationStrategy();private String prefix = "";private Method redisConnectionSet_2_0;public MyRedisTokenStore(RedisConnectionFactory connectionFactory) {this.connectionFactory = connectionFactory;if (springDataRedis_2_0) {this.loadRedisConnectionMethods_2_0();}}public void setAuthenticationKeyGenerator(AuthenticationKeyGenerator authenticationKeyGenerator) {this.authenticationKeyGenerator = authenticationKeyGenerator;}public void setSerializationStrategy(RedisTokenStoreSerializationStrategy serializationStrategy) {this.serializationStrategy = serializationStrategy;}public void setPrefix(String prefix) {this.prefix = prefix;}private void loadRedisConnectionMethods_2_0() {this.redisConnectionSet_2_0 = ReflectionUtils.findMethod(RedisConnection.class, "set", new Class[]{byte[].class, byte[].class});}private RedisConnection getConnection() {return this.connectionFactory.getConnection();}private byte[] serialize(Object object) {return this.serializationStrategy.serialize(object);}private byte[] serializeKey(String object) {return this.serialize(this.prefix + object);}private OAuth2AccessToken deserializeAccessToken(byte[] bytes) {return (OAuth2AccessToken)this.serializationStrategy.deserialize(bytes, OAuth2AccessToken.class);}private OAuth2Authentication deserializeAuthentication(byte[] bytes) {return (OAuth2Authentication)this.serializationStrategy.deserialize(bytes, OAuth2Authentication.class);}private OAuth2RefreshToken deserializeRefreshToken(byte[] bytes) {return (OAuth2RefreshToken)this.serializationStrategy.deserialize(bytes, OAuth2RefreshToken.class);}private byte[] serialize(String string) {return this.serializationStrategy.serialize(string);}private String deserializeString(byte[] bytes) {return this.serializationStrategy.deserializeString(bytes);}public OAuth2AccessToken getAccessToken(OAuth2Authentication authentication) {String key = this.authenticationKeyGenerator.extractKey(authentication);byte[] serializedKey = this.serializeKey("auth_to_access:" + key);byte[] bytes = null;RedisConnection conn = this.getConnection();try {bytes = conn.get(serializedKey);} finally {conn.close();}OAuth2AccessToken accessToken = this.deserializeAccessToken(bytes);if (accessToken != null) {OAuth2Authentication storedAuthentication = this.readAuthentication(accessToken.getValue());if (storedAuthentication == null || !key.equals(this.authenticationKeyGenerator.extractKey(storedAuthentication))) {this.storeAccessToken(accessToken, authentication);}}return accessToken;}public OAuth2Authentication readAuthentication(OAuth2AccessToken token) {return this.readAuthentication(token.getValue());}public OAuth2Authentication readAuthentication(String token) {byte[] bytes = null;RedisConnection conn = this.getConnection();try {bytes = conn.get(this.serializeKey("auth:" + token));} finally {conn.close();}OAuth2Authentication var4 = this.deserializeAuthentication(bytes);return var4;}public OAuth2Authentication readAuthenticationForRefreshToken(OAuth2RefreshToken token) {return this.readAuthenticationForRefreshToken(token.getValue());}public OAuth2Authentication readAuthenticationForRefreshToken(String token) {RedisConnection conn = this.getConnection();OAuth2Authentication var5;try {byte[] bytes = conn.get(this.serializeKey("refresh_auth:" + token));OAuth2Authentication auth = this.deserializeAuthentication(bytes);var5 = auth;} finally {conn.close();}return var5;}public void storeAccessToken(OAuth2AccessToken token, OAuth2Authentication authentication) {byte[] serializedAccessToken = this.serialize((Object)token);byte[] serializedAuth = this.serialize((Object)authentication);byte[] accessKey = this.serializeKey("access:" + token.getValue());byte[] authKey = this.serializeKey("auth:" + token.getValue());byte[] authToAccessKey = this.serializeKey("auth_to_access:" + this.authenticationKeyGenerator.extractKey(authentication));byte[] approvalKey = this.serializeKey("uname_to_access:" + getApprovalKey(authentication));byte[] clientId = this.serializeKey("client_id_to_access:" + authentication.getOAuth2Request().getClientId());RedisConnection conn = this.getConnection();try {conn.openPipeline();if (springDataRedis_2_0) {try {this.redisConnectionSet_2_0.invoke(conn, accessKey, serializedAccessToken);this.redisConnectionSet_2_0.invoke(conn, authKey, serializedAuth);this.redisConnectionSet_2_0.invoke(conn, authToAccessKey, serializedAccessToken);} catch (Exception var24) {throw new RuntimeException(var24);}} else {conn.set(accessKey, serializedAccessToken);conn.set(authKey, serializedAuth);conn.set(authToAccessKey, serializedAccessToken);}if (!authentication.isClientOnly()) {conn.sAdd(approvalKey, new byte[][]{serializedAccessToken});}conn.sAdd(clientId, new byte[][]{serializedAccessToken});if (token.getExpiration() != null) {int seconds = token.getExpiresIn();conn.expire(accessKey, (long)seconds);conn.expire(authKey, (long)seconds);conn.expire(authToAccessKey, (long)seconds);conn.expire(clientId, (long)seconds);conn.expire(approvalKey, (long)seconds);}OAuth2RefreshToken refreshToken = token.getRefreshToken();if (refreshToken != null && refreshToken.getValue() != null) {byte[] refresh = this.serialize(token.getRefreshToken().getValue());byte[] auth = this.serialize(token.getValue());byte[] refreshToAccessKey = this.serializeKey("refresh_to_access:" + token.getRefreshToken().getValue());byte[] accessToRefreshKey = this.serializeKey("access_to_refresh:" + token.getValue());if (springDataRedis_2_0) {try {this.redisConnectionSet_2_0.invoke(conn, refreshToAccessKey, auth);this.redisConnectionSet_2_0.invoke(conn, accessToRefreshKey, refresh);} catch (Exception var23) {throw new RuntimeException(var23);}} else {conn.set(refreshToAccessKey, auth);conn.set(accessToRefreshKey, refresh);}if (refreshToken instanceof ExpiringOAuth2RefreshToken) {ExpiringOAuth2RefreshToken expiringRefreshToken = (ExpiringOAuth2RefreshToken)refreshToken;Date expiration = expiringRefreshToken.getExpiration();if (expiration != null) {int seconds = Long.valueOf((expiration.getTime() - System.currentTimeMillis()) / 1000L).intValue();conn.expire(refreshToAccessKey, (long)seconds);conn.expire(accessToRefreshKey, (long)seconds);}}}conn.closePipeline();} finally {conn.close();}}private static String getApprovalKey(OAuth2Authentication authentication) {String userName = authentication.getUserAuthentication() == null ? "" : authentication.getUserAuthentication().getName();return getApprovalKey(authentication.getOAuth2Request().getClientId(), userName);}private static String getApprovalKey(String clientId, String userName) {return clientId + (userName == null ? "" : ":" + userName);}public void removeAccessToken(OAuth2AccessToken accessToken) {this.removeAccessToken(accessToken.getValue());}public OAuth2AccessToken readAccessToken(String tokenValue) {byte[] key = this.serializeKey("access:" + tokenValue);byte[] bytes = null;RedisConnection conn = this.getConnection();try {bytes = conn.get(key);} finally {conn.close();}OAuth2AccessToken var5 = this.deserializeAccessToken(bytes);return var5;}public void removeAccessToken(String tokenValue) {byte[] accessKey = this.serializeKey("access:" + tokenValue);byte[] authKey = this.serializeKey("auth:" + tokenValue);byte[] accessToRefreshKey = this.serializeKey("access_to_refresh:" + tokenValue);RedisConnection conn = this.getConnection();try {conn.openPipeline();conn.get(accessKey);conn.get(authKey);conn.del(new byte[][]{accessKey});conn.del(new byte[][]{accessToRefreshKey});conn.del(new byte[][]{authKey});List<Object> results = conn.closePipeline();byte[] access = (byte[])((byte[])results.get(0));byte[] auth = (byte[])((byte[])results.get(1));OAuth2Authentication authentication = this.deserializeAuthentication(auth);if (authentication != null) {String key = this.authenticationKeyGenerator.extractKey(authentication);byte[] authToAccessKey = this.serializeKey("auth_to_access:" + key);byte[] unameKey = this.serializeKey("uname_to_access:" + getApprovalKey(authentication));byte[] clientId = this.serializeKey("client_id_to_access:" + authentication.getOAuth2Request().getClientId());conn.openPipeline();conn.del(new byte[][]{authToAccessKey});conn.sRem(unameKey, new byte[][]{access});conn.sRem(clientId, new byte[][]{access});conn.del(new byte[][]{this.serialize("access:" + key)});conn.closePipeline();}} finally {conn.close();}}public void storeRefreshToken(OAuth2RefreshToken refreshToken, OAuth2Authentication authentication) {byte[] refreshKey = this.serializeKey("refresh:" + refreshToken.getValue());byte[] refreshAuthKey = this.serializeKey("refresh_auth:" + refreshToken.getValue());byte[] serializedRefreshToken = this.serialize((Object)refreshToken);RedisConnection conn = this.getConnection();try {conn.openPipeline();if (springDataRedis_2_0) {try {this.redisConnectionSet_2_0.invoke(conn, refreshKey, serializedRefreshToken);this.redisConnectionSet_2_0.invoke(conn, refreshAuthKey, this.serialize((Object)authentication));} catch (Exception var13) {throw new RuntimeException(var13);}} else {conn.set(refreshKey, serializedRefreshToken);conn.set(refreshAuthKey, this.serialize((Object)authentication));}if (refreshToken instanceof ExpiringOAuth2RefreshToken) {ExpiringOAuth2RefreshToken expiringRefreshToken = (ExpiringOAuth2RefreshToken)refreshToken;Date expiration = expiringRefreshToken.getExpiration();if (expiration != null) {int seconds = Long.valueOf((expiration.getTime() - System.currentTimeMillis()) / 1000L).intValue();conn.expire(refreshKey, (long)seconds);conn.expire(refreshAuthKey, (long)seconds);}}conn.closePipeline();} finally {conn.close();}}public OAuth2RefreshToken readRefreshToken(String tokenValue) {byte[] key = this.serializeKey("refresh:" + tokenValue);byte[] bytes = null;RedisConnection conn = this.getConnection();try {bytes = conn.get(key);} finally {conn.close();}OAuth2RefreshToken var5 = this.deserializeRefreshToken(bytes);return var5;}public void removeRefreshToken(OAuth2RefreshToken refreshToken) {this.removeRefreshToken(refreshToken.getValue());}public void removeRefreshToken(String tokenValue) {byte[] refreshKey = this.serializeKey("refresh:" + tokenValue);byte[] refreshAuthKey = this.serializeKey("refresh_auth:" + tokenValue);byte[] refresh2AccessKey = this.serializeKey("refresh_to_access:" + tokenValue);byte[] access2RefreshKey = this.serializeKey("access_to_refresh:" + tokenValue);RedisConnection conn = this.getConnection();try {conn.openPipeline();conn.del(new byte[][]{refreshKey});conn.del(new byte[][]{refreshAuthKey});conn.del(new byte[][]{refresh2AccessKey});conn.del(new byte[][]{access2RefreshKey});conn.closePipeline();} finally {conn.close();}}public void removeAccessTokenUsingRefreshToken(OAuth2RefreshToken refreshToken) {this.removeAccessTokenUsingRefreshToken(refreshToken.getValue());}private void removeAccessTokenUsingRefreshToken(String refreshToken) {byte[] key = this.serializeKey("refresh_to_access:" + refreshToken);List<Object> results = null;RedisConnection conn = this.getConnection();try {conn.openPipeline();conn.get(key);conn.del(new byte[][]{key});results = conn.closePipeline();} finally {conn.close();}if (results != null) {byte[] bytes = (byte[])((byte[])results.get(0));String accessToken = this.deserializeString(bytes);if (accessToken != null) {this.removeAccessToken(accessToken);}}}private List<byte[]> getByteLists(byte[] approvalKey, RedisConnection conn) {Long size = conn.sCard(approvalKey);List<byte[]> byteList = new ArrayList(size.intValue());Cursor cursor = conn.sScan(approvalKey, ScanOptions.NONE);while(cursor.hasNext()) {Object next = cursor.next();byteList.add(next.toString().getBytes(StandardCharsets.UTF_8));}return byteList;}public Collection<OAuth2AccessToken> findTokensByClientIdAndUserName(String clientId, String userName) {byte[] approvalKey = this.serializeKey("uname_to_access:" + getApprovalKey(clientId, userName));List<byte[]> byteList = null;RedisConnection conn = this.getConnection();try {byteList = this.getByteLists(approvalKey, conn);} finally {conn.close();}if (byteList != null && byteList.size() != 0) {List<OAuth2AccessToken> accessTokens = new ArrayList(byteList.size());Iterator var7 = byteList.iterator();while(var7.hasNext()) {byte[] bytes = (byte[])var7.next();OAuth2AccessToken accessToken = this.deserializeAccessToken(bytes);accessTokens.add(accessToken);}return Collections.unmodifiableCollection(accessTokens);} else {return Collections.emptySet();}}public Collection<OAuth2AccessToken> findTokensByClientId(String clientId) {byte[] key = this.serializeKey("client_id_to_access:" + clientId);List<byte[]> byteList = null;RedisConnection conn = this.getConnection();try {byteList = this.getByteLists(key, conn);} finally {conn.close();}if (byteList != null && byteList.size() != 0) {List<OAuth2AccessToken> accessTokens = new ArrayList(byteList.size());Iterator var6 = byteList.iterator();while(var6.hasNext()) {byte[] bytes = (byte[])var6.next();OAuth2AccessToken accessToken = this.deserializeAccessToken(bytes);accessTokens.add(accessToken);}return Collections.unmodifiableCollection(accessTokens);} else {return Collections.emptySet();}}
}

3.自定义序列化类

package com.enterprise.auth.config;import com.google.gson.Gson;
import org.springframework.security.oauth2.provider.token.store.redis.BaseRedisTokenStoreSerializationStrategy;import java.nio.charset.StandardCharsets;
import java.util.Map;public class MyRedisTokenStoreSerializationStrategy extends BaseRedisTokenStoreSerializationStrategy {@Override//反序列化内部protected <T> T deserializeInternal(byte[] bytes, Class<T> aClass) {String s = new String(bytes);Gson gson = new Gson();return gson.fromJson(s,aClass);}@Override//反序列化字符串内部protected String deserializeStringInternal(byte[] bytes) {return new String(bytes);}@Override//序列化内部protected byte[] serializeInternal(Object o) {Gson gson = new Gson();String json = gson.toJson(o);return json.getBytes(StandardCharsets.UTF_8);}@Override//序列化内部protected byte[] serializeInternal(String s) {return  s.getBytes(StandardCharsets.UTF_8);}
}

4.配置使用redis类型的 TokenStore

package com.enterprise.auth.config;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.security.oauth2.provider.token.TokenStore;@Configuration
public class MyRedisTokenStoreConfig {@Autowiredprivate RedisConnectionFactory redisConnectionFactory;@Beanpublic TokenStore tokenStore() {MyRedisTokenStore redisTokenStore = new MyRedisTokenStore(redisConnectionFactory);return redisTokenStore;}
}

5.完成认证模块的编写后,测试登录

 

 json已经保存在数据库了

但是!!!!!,保存没问题,取出来的时候就有问题了,把这三个文件复制到资源服务器,让资源服务器也用MyRedisTokenStore 的方式读取权限信息.

 然后访问,到json权限信息转成实体类的时候,就有问题了,各种各样oauth2 中的数据实体类,没有构造方法,无法创建对象,先转成map在手动新建对象同样不行,

 redis中的配置已经读到了

 但是需要实例化的对象类路径,这么长一串,没有构造方法,无法新建对象.

报错>>>

 

结束<<<<<<<<

相关文章:

spring security + oauth2 使用RedisTokenStore 以json格式存储

1.项目架构 2.自己对 TokenStore 的 redis实现 package com.enterprise.auth.config;import org.springframework.data.redis.connection.RedisConnection; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis…...

css position: sticky;实现上下粘性布局,中间区域滚动

sticky主要解决的问题 1、使用absolute和fixed中间区域需要定义高度2、使用absolute和fixed底部需要写padding-bottom 避免列表被遮挡住一部分&#xff08;底部是浮窗的时候&#xff0c;需要动态的现实隐藏&#xff09; <!DOCTYPE html> <html lang"en"&…...

解密HTTP代理爬虫中的IP代理选择与管理策略

在当今数据驱动的世界中&#xff0c;HTTP代理爬虫作为一项重要的数据采集工具&#xff0c;其成功与否往往取决于IP代理的选择与管理策略。作为一家专业的HTTP代理产品供应商&#xff0c;我们深知IP代理在数据采集中的重要性。在本文中&#xff0c;我们将分享一些关于HTTP代理爬…...

pytorch入门

详细安装教程和环境配置可以看&#xff1a;Python深度学习&#xff1a;安装Anaconda、PyTorch&#xff08;GPU版&#xff09;库与PyCharm_哔哩哔哩_bilibili 跟学课程&#xff1a;B站我是土堆 pytorch中两个实用函数&#xff1a; dir()&#xff1a;打开 help():说明书…...

Redis | 主从模式

Redis | 主从模式 1. 简介 Redis主从模式&#xff08;Replication&#xff09;是Redis提供的一种数据备份和高可用性解决方案。通过主从复制&#xff0c;可以将一个Redis服务器的数据复制到其他多个从服务器&#xff0c;从而实现数据的备份和读写分离&#xff0c;提高系统的性…...

C# Blazor 学习笔记(8):row/col布局开发

文章目录 前言相关文章代码row和col组件B_rowB_col结构 使用 前言 可能是我用的element ui和 uView这种第三方组件用的太多了。我上来就希望能使用这些组件。但是目前Blazor目前的生态其实并不完善&#xff0c;所以很多组件要我们自己写。 我们对组件的要求是 我们在组件化一共…...

金融供应链智能合约 -- 智能合约实例

前提 Ownable:监管者合约,有一个函数能转让监管者。 SupplyChainFin:供应链金融合约,银行、公司信息上链&#xff0c;公司和银行之间的转账。 发票&#xff1a;记录者交易双方和交易金额等的一种记录数据。如:我在超市买了一瓶水,超市给我开了一张发票。 Ownable // SPDX-…...

论文《Contrastive Meta Learning with Behavior Multiplicity for Recommendation》阅读

论文《Contrastive Meta Learning with Behavior Multiplicity for Recommendation》阅读 论文概况论文主要贡献Background & Motivation方法论单行为图神经网络&#xff08;Behavior-aware GNN&#xff09;多行为对比学习元对比编码模型训练 实验部分论文总结 论文概况 今…...

K8S 部署 RocketMQ

文章目录 添加模板部署本地访问 集群使用 kubesphere 作为工具 添加模板 添加 helm 模板 helm repo add rocketmq-repo https://helm-charts.itboon.top/rocketmq helm repo update rocketmq-repo编写 value.yaml 文件 配置主从节点的个数&#xff0c;例子为单节点 broker:…...

[Docker]入门之docker-compose

一&#xff0c;Docker-compose简介 1&#xff0c;Docker-compose简介 Docker-Compose项目是Docker官方的开源项目&#xff0c;负责实现对Docker容器集群的快速编排。 Docker-Compose将所管理的容器分为三层&#xff0c;分别是工程&#xff08;project&#xff09;&#xff0c…...

SAP ABAP中使用函数ALSM_EXCEL_TO_INTERNAL_TABLE读取EXCEL中不同的SHEET数据

SAP提供了标准的读取EXCEL的函数&#xff08;ALSM_EXCEL_TO_INTERNAL_TABLE&#xff09;&#xff0c;但是此标准函数无法满足对同一EXCEL 进行不同SHEET的数据读取&#xff0c;一下方法就是教你如何通过修改程序来实现ALSM_EXCEL_TO_INTERNAL_TABLE读取多个SHEET&#xff1b; …...

Rust 编程小技巧摘选(6)

目录 Rust 编程小技巧(6) 1. 打印字符串 2. 重复打印字串 3. 自定义函数 4. 遍历动态数组 5. 遍历二维数组 6. 同时遍历索引和值 7. 迭代器方法的区别 8. for_each() 用法 9. 分离奇数和偶数 10. 判断素数&#xff08;质数&#xff09; Rust 编程小技巧(6) 1. 打印…...

如何保证Redis缓存和数据库的一致性问题

熟练掌握Redis缓存技术&#xff1f; 那么请问Redis缓存中有几种读写策略&#xff0c;又是如何保证与数据库的一致性问题 今天来聊一聊常用的三种缓存读写策略 Cache Aside Pattern Cache Aside Pattern 是我们平时使用比较多的一个缓存读写模式&#xff0c;比较适合读请求比…...

【数据分析入门】人工智能、数据分析和深度学习是什么关系?如何快速入门 Python Pandas?

目录 一、前言二、数据分析和深度学习的区别三、人工智能四、深度学习五、Pandas六、Pandas数据结构6.1 Series - 序列6.2 DataFrame - 数据框 七、输入、输出7.1 读取/写入CSV7.2 读取/写入Excel7.3 读取和写入 SQL 查询及数据库表 八、调用帮助九、选择(这里可以参考上一篇文…...

JavaScript 里三个点 ... 的用法

// table表头数据let tableHeadData deepClone(data);let tableCacheData [];//表格缓存对比if (!parent && isCacheHeadData) {// 缓存数据keylet tableCacheKey ${window.location.pathname}-${$self.attr(id)}if (localStorage.getItem(tableCacheKey)) {//根据缓…...

Linux修改系统语言

sudo dpkg-reconfigure locales 按pagedown键&#xff0c;移动红色光标到 zh_CN.UTF-8 UTF-8&#xff0c;空格标记*号&#xff08;没标记下一页没有这一项&#xff09;&#xff0c;回车。 下一页选择 zh_CN.UTF-8。 如果找不到 dpkg-reconfigure whereis dpkg-reconfigure …...

Spring注解开发

目录 1、简介 2、原始注解 2.1、注解种类 2.2、组件扫描 2.3、具体使用 2.3.1、xml配置 2.3.2、注解配置 3、⭐新注解 3.1、新注解种类 3.2、实践 3.3、运行结果 3.4、警告信息 1、简介 Spring框架提供了许多注解&#xff0c;用于在Java类中进行配置和标记&#xf…...

图像处理库(Opencv, Matplotlib, PIL)以及三者之间的转换

文章目录 1. Opencv2. Matplotlib3. PIL4. 三者的区别和相互转换5. Torchvision 中的相关转换库5.1 ToPILImage([mode])5.2 ToTensor5.3 PILToTensor 1. Opencv opencv的基本图像类型可以和numpy数组相互转化&#xff0c;因此可以直接调用torch.from_numpy(img) 将图像转换成t…...

html+Vue+封装axios实现发送请求

在html中使用Vue和Axios时&#xff0c;可以在HTML中引入Vue库和Axios库&#xff0c;然后使用Vue的语法和指令来创建Vue组件和模板。在Vue组件中&#xff0c;你可以使用Axios发送HTTP请求来获取数据&#xff0c;并将数据绑定到Vue模板中进行展示。 <template><div>&…...

GoogLeNet卷积神经网络输出数据形参分析-笔记

GoogLeNet卷积神经网络输出数据形参分析-笔记 分析结果为&#xff1a; 输入数据形状:[10, 3, 224, 224] 最后输出结果&#xff1a;linear_0 [10, 1] [1024, 1] [1] 子空间执行逻辑 def forward_old(self, x):# 支路1只包含一个1x1卷积p1 F.relu(self.p1_1(x))# 支路2包含 1…...

Python爬虫实战:研究MechanicalSoup库相关技术

一、MechanicalSoup 库概述 1.1 库简介 MechanicalSoup 是一个 Python 库,专为自动化交互网站而设计。它结合了 requests 的 HTTP 请求能力和 BeautifulSoup 的 HTML 解析能力,提供了直观的 API,让我们可以像人类用户一样浏览网页、填写表单和提交请求。 1.2 主要功能特点…...

DAY 47

三、通道注意力 3.1 通道注意力的定义 # 新增&#xff1a;通道注意力模块&#xff08;SE模块&#xff09; class ChannelAttention(nn.Module):"""通道注意力模块(Squeeze-and-Excitation)"""def __init__(self, in_channels, reduction_rat…...

【第二十一章 SDIO接口(SDIO)】

第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...

C++中string流知识详解和示例

一、概览与类体系 C 提供三种基于内存字符串的流&#xff0c;定义在 <sstream> 中&#xff1a; std::istringstream&#xff1a;输入流&#xff0c;从已有字符串中读取并解析。std::ostringstream&#xff1a;输出流&#xff0c;向内部缓冲区写入内容&#xff0c;最终取…...

MySQL账号权限管理指南:安全创建账户与精细授权技巧

在MySQL数据库管理中&#xff0c;合理创建用户账号并分配精确权限是保障数据安全的核心环节。直接使用root账号进行所有操作不仅危险且难以审计操作行为。今天我们来全面解析MySQL账号创建与权限分配的专业方法。 一、为何需要创建独立账号&#xff1f; 最小权限原则&#xf…...

JVM 内存结构 详解

内存结构 运行时数据区&#xff1a; Java虚拟机在运行Java程序过程中管理的内存区域。 程序计数器&#xff1a; ​ 线程私有&#xff0c;程序控制流的指示器&#xff0c;分支、循环、跳转、异常处理、线程恢复等基础功能都依赖这个计数器完成。 ​ 每个线程都有一个程序计数…...

QT3D学习笔记——圆台、圆锥

类名作用Qt3DWindow3D渲染窗口容器QEntity场景中的实体&#xff08;对象或容器&#xff09;QCamera控制观察视角QPointLight点光源QConeMesh圆锥几何网格QTransform控制实体的位置/旋转/缩放QPhongMaterialPhong光照材质&#xff08;定义颜色、反光等&#xff09;QFirstPersonC…...

Selenium常用函数介绍

目录 一&#xff0c;元素定位 1.1 cssSeector 1.2 xpath 二&#xff0c;操作测试对象 三&#xff0c;窗口 3.1 案例 3.2 窗口切换 3.3 窗口大小 3.4 屏幕截图 3.5 关闭窗口 四&#xff0c;弹窗 五&#xff0c;等待 六&#xff0c;导航 七&#xff0c;文件上传 …...

免费数学几何作图web平台

光锐软件免费数学工具&#xff0c;maths,数学制图&#xff0c;数学作图&#xff0c;几何作图&#xff0c;几何&#xff0c;AR开发,AR教育,增强现实,软件公司,XR,MR,VR,虚拟仿真,虚拟现实,混合现实,教育科技产品,职业模拟培训,高保真VR场景,结构互动课件,元宇宙http://xaglare.c…...

Python Einops库:深度学习中的张量操作革命

Einops&#xff08;爱因斯坦操作库&#xff09;就像给张量操作戴上了一副"语义眼镜"——让你用人类能理解的方式告诉计算机如何操作多维数组。这个基于爱因斯坦求和约定的库&#xff0c;用类似自然语言的表达式替代了晦涩的API调用&#xff0c;彻底改变了深度学习工程…...