- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我在我的 spring boot 应用程序上使用了 redis 缓存,我需要将未知类型的响应对象存储到 redisTemplate 中。所以我在我的 redisTemplates 上使用 kryoSerialzation,
Exception :
org.objenesis.ObjenesisException: java.io.NotSerializableException: class sample.data.redis.model.Student not serializable
at org.objenesis.strategy.SerializingInstantiatorStrategy.newInstantiatorOf(SerializingInstantiatorStrategy.java:58)
at com.esotericsoftware.kryo.Kryo.newInstantiator(Kryo.java:1127)
at com.esotericsoftware.kryo.Kryo.newInstance(Kryo.java:1136)
Note:
我无法在我的响应对象上实现 Serializable 接口(interface),因为它在我的应用程序中是动态的和未知的类型
pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
<dependency>
<groupId>com.esotericsoftware</groupId>
<artifactId>kryo</artifactId>
<version>4.0.1</version>
</dependency>
public class KryoRedisSerializer implements RedisSerializer<Object>{
private final ThreadLocal<Kryo> kryoThreadLocal = new ThreadLocal<Kryo>() {
@Override
protected Kryo initialValue() {
Kryo kryo = new Kryo();
kryo.register(Object.class);
return kryo;
}
};
public KryoRedisSerializer() {
kryoThreadLocal.get().setInstantiatorStrategy((InstantiatorStrategy) new SerializingInstantiatorStrategy());
}
@Override
public byte[] serialize(Object object) throws SerializationException {
// TODO Auto-generated method stub
if (object == null) {
return new byte[0];
}
try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
Output output = new Output(outputStream);
kryoThreadLocal.get().writeClassAndObject(output, object);
return output.toBytes();
} catch (IOException e) {
throw new SerializationException("Failed Serialization", e);
}
}
@Override
public Object deserialize(byte[] bytes) throws SerializationException {
// TODO Auto-generated method stub
if (bytes == null || bytes.length == 0) {
return null;
}
try (Input input = new Input(bytes)) {
return kryoThreadLocal.get().readClassAndObject(input);
}
}
}
}
@Configuration
public class SpringRadisConfig {
@Bean
public JedisConnectionFactory connectionFactory() {
JedisConnectionFactory connectionFactory = new JedisConnectionFactory();
connectionFactory.setHostName("localhost");
connectionFactory.setPort(6379);
return connectionFactory;
}
@Bean
public RedisTemplate<String, Object> redisTemplate() {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(connectionFactory());
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(kryoRedisSSerializer());
redisTemplate.setHashValueSerializer(new JdkSerializationRedisSerializer());
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
@Bean
public RedisSerializer<Object> kryoRedisSSerializer() {
return new KryoRedisSSerializer();
}
}
SampleRedisApplication.java(主要方法)
@SpringBootApplication
@ComponentScan(basePackages = "sample.data.redis")
public class SampleRedisApplication implements CommandLineRunner {
@Autowired
private StringRedisTemplate template;
@Autowired
private SpringRadisConfig redisConfig;
@Override
public void run(String... args) throws Exception {/*
ValueOperations<String, String> ops = this.template.opsForValue();
String key = "spring.boot.redis.test";
if (!this.template.hasKey(key)) {
ops.set(key, "Hi Ratheesh ");
}
System.out.println("Found key " + key + ", value=" + ops.get(key));*/
RedisTemplate<String, Object> redisTemplate = redisConfig.redisTemplate();
ValueOperations<String, Object> values = redisTemplate.opsForValue();
try {
Student student = new Student(1L, "Vishal");
values.set("student", student);
Student std = (Student) values.get("student");
System.out.println(std.getId());
System.out.println(std.getName());
} catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws Exception {
// Close the context so it doesn't stay awake listening for redis
SpringApplication.run(SampleRedisApplication.class, args).close();
}
}
假设 student 是我从远程 API 获取的响应对象,实际上我的 API 响应应用程序中没有任何模型对象定义 (POJO),因为我的 API 响应类型是 (Type T) 即动态节点
我在 github 中找到了解决方案但这不起作用(将对象转换为数组并将其存储在 Redis 中)
最佳答案
后来我决定使用 Redisson 而不是 Jedis 客户端,这可以解决我的序列化问题
CacheManager Config for cachable/cachPut/cacheEvict注解类型实现
@Configuration
@EnableCaching
public class RedissonCacheConfiguration {
/**
* Property holder for holding the Redis cache configuration properties like
* <code>Host, Port, Session Duration</code>, etc.
*
* <p>
* Bean with name <code>redisCacheConfigProperties</code> should be populated with these
* configuration properties and then loaded in the application context.
*/
@Autowired
private RedissonConfigProperties redisCacheConfigProperties;
/**
* Sets the Redis cache configuration properties.
*
* @param redisCacheConfigProperties Property holder for holding the Redis cache configuration
* properties.
*/
public void setRedissonConfigProperties(
final RedissonConfigProperties redisCacheConfigProperties) {
this.redisCacheConfigProperties = redisCacheConfigProperties;
}
@Bean
public CacheManager cacheManager() {
CacheManager cacheManager = new RedissonSpringCacheManager(redissonClient(), getCacheConfigs());
return cacheManager;
}
@Bean
public Map<String, CacheConfig> getCacheConfigs(){
Map<String, CacheConfig> config = new HashMap<String, CacheConfig>();
// ttl = 24 mins, maxIdleTime = 12 mins
config.put("testCache", new CacheConfig(24*60*1000, 12*60*1000));
return config;
}
@Bean
public RedissonClient redissonClient() {
Config config = new Config();
SingleServerConfig singleServerConfig = config.useSingleServer();
// format as redis://127.0.0.1:7181 or rediss://127.0.0.1:7181 for SSL
String schema = redisCacheConfigProperties.isSsl() ? "rediss://" : "";
singleServerConfig.setAddress(schema + redisCacheConfigProperties.getHost() + ":" + redisCacheConfigProperties.getPort());
singleServerConfig.setDatabase(redisCacheConfigProperties.getDatabase());
if (redisCacheConfigProperties.getPassword() != null) {
singleServerConfig.setPassword(redisCacheConfigProperties.getPassword());
}
return Redisson.create(config);
}
}
可缓存注释使用
@Cacheable(cacheNames = "#cacheProperies.cacheName", key = "#cacheProperies.cacheKey", unless = "#result==null")
public Object fetchData( final CacheProperties cacheProperies) {
// If there is no cached data by the given key, then we will return NULL.
return doTheOperation();
}
@CacheEvict(cacheNames = "#cacheProperies.cacheName", key = "#cacheProperies.cacheKey")
public void removeData(final CacheProperties cacheProperies) {
// Deletes the Cached CartInfo.
}
@CachePut(cacheNames = "#cacheProperies.cacheName", key = "#cacheProperies.cacheKey", unless = "#result==null")
public Object cacheData(final Object object, final CacheProperties cacheProperies ) {
// Returns the same object which is received as parameter,
// so that this object will be cached by key '... reference'.
return doTheOperation();
}
关于java - 如何使用 kryoSerialzation 将非序列化对象存储到重新缓存中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48247824/
我正在运行一个辅助角色,并检查 Azure 上托管的存储中是否存在数据。当我将连接字符串用于经典类型的存储时,我的代码可以正常工作,但是当我连接到 V2 Azure 存储时,它会抛出此异常。 “远程服
在我的应用程序的主页上,我正在进行 AJAX 调用以获取应用程序各个部分所需的大量数据。该调用如下所示: var url = "/Taxonomy/GetTaxonomyList/" $.getJSO
大家好,我正在尝试将我的商店导入我的 Vuex Route-Gard。 路由器/auth-guard.js import {store} from '../store' export default
我正在使用 C# 控制台应用程序 (.NET Core 3.1) 从 Azure Blob 存储读取大量图像文件并生成这些图像的缩略图。新图像将保存回 Azure,并将 Blob ID 存储在我们的数
我想将 Mlflow 设置为具有以下组件: 后端存储(本地):在本地使用 SQLite 数据库存储 Mlflow 实体(run_id、params、metrics...) 工件存储(远程):使用 Az
我正在使用 C# 控制台应用程序 (.NET Core 3.1) 从 Azure Blob 存储读取大量图像文件并生成这些图像的缩略图。新图像将保存回 Azure,并将 Blob ID 存储在我们的数
我想将 Mlflow 设置为具有以下组件: 后端存储(本地):在本地使用 SQLite 数据库存储 Mlflow 实体(run_id、params、metrics...) 工件存储(远程):使用 Az
我的 Windows 计算机上的本地文件夹中有一些图像。我想将所有图像上传到同一容器中的同一 blob。 我知道如何使用 Azure Storage SDKs 上传单个文件BlockBlobServi
我尝试发出 GET 请求来获取我的 Azure Blob 存储帐户的帐户详细信息,但每次都显示身份验证失败。谁能判断形成的 header 或签名字符串是否正确或是否存在其他问题? 代码如下: cons
这是用于编写 JSON 的 NeutralinoJS 存储 API。是否可以更新 JSON 文件(推送数据),而不仅仅是用新的 JS 对象覆盖数据。怎么做到的??? // Javascript
我有一个并行阶段设置,想知道是否可以在嵌套阶段之前运行脚本,所以像这样: stage('E2E-PR-CYPRESS') { when { allOf {
我想从命令行而不是从GUI列出VirtualBox VM的详细信息。我对存储细节特别感兴趣。 当我在GUI中单击VM时,可以看到包括存储部分在内的详细信息: 但是到目前为止,我还没有找到通过命令行执行
我有大约 3500 个防洪设施,我想将它们表示为一个网络来确定流动路径(本质上是一个有向图)。我目前正在使用 SqlServer 和 CTE 来递归检查所有节点及其上游组件,只要上游路径没有 fork
谁能告诉我 jquery data() 在哪里存储数据以及何时删除以及如何删除? 如果我用它来存储ajax调用结果,会有性能问题吗? 例如: $("body").data("test", { myDa
有人可以建议如何为 Firebase 存储中的文件设置备份。我能够备份数据库,但不确定如何为 firebase 存储中的文件(我有图像)设置定期备份。 最佳答案 如何进行 Firebase 存储的本地
我最近开始使用 firebase 存储和 firebase 功能。现在我一直在开发从功能到存储的文件上传。 我已经让它工作了(上传完成并且文件出现在存储部分),但是,图像永远保持这样(永远在右侧加载)
我想只允许用户将文件上传到他们自己的存储桶中,最大文件大小为 1MB,仍然允许他们删除文件。我添加了以下内容: match /myusers/{userId}/{allPaths=**} { al
使用生命周期管理策略将容器的内容从冷访问层移动到存档。我正在尝试以下策略,希望它能在一天后将该容器中的所有文件移动到存档层,但事实并非如此在职的。我设置了选择标准“一天未使用后”。 这是 json 代
对于连接到 Azure 存储端点,有 http 和 https 两个选项。 第一。 https 会带来开销,可能是 5%-10%,但我不支付同一个数据中心的费用。 第二。 http 更快,但 Auth
有人可以帮我理解这一点吗?我创建了Virtual Machine in Azure running Windows Server 2012 。我注意到 Azure 自动创建了一个存储帐户。当我进入该存
我是一名优秀的程序员,十分优秀!