mirror of
https://gitee.com/kekingcn/file-online-preview.git
synced 2026-11-11 13:50:44 +00:00
fix: avoid NPE when previewing images with redis cache
CacheServiceRedisImpl#getImgCache(String) passed the key straight to Redisson, which throws NullPointerException (map key can't be null) for a null key. Every single-image preview hits this path because compressFileKey is only set for images inside an archive, so with cache.type=redis the preview endpoint always returned HTTP 500. Return an empty list for empty keys, matching CacheServiceJDKImpl. Fixes #793
This commit is contained in:
@@ -1,12 +1,14 @@
|
||||
package cn.keking.service.cache.impl;
|
||||
|
||||
import cn.keking.service.cache.CacheService;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.redisson.api.RBlockingQueue;
|
||||
import org.redisson.api.RMapCache;
|
||||
import org.redisson.api.RedissonClient;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -68,6 +70,9 @@ public class CacheServiceRedisImpl implements CacheService {
|
||||
|
||||
@Override
|
||||
public List<String> getImgCache(String key) {
|
||||
if (StringUtils.isEmpty(key)) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
RMapCache<String, List<String>> convertedList = redissonClient.getMapCache(FILE_PREVIEW_IMGS_KEY);
|
||||
return convertedList.get(key);
|
||||
}
|
||||
|
||||
65
server/src/test/java/cn/keking/service/cache/impl/CacheServiceRedisImplTests.java
vendored
Normal file
65
server/src/test/java/cn/keking/service/cache/impl/CacheServiceRedisImplTests.java
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
package cn.keking.service.cache.impl;
|
||||
|
||||
import cn.keking.service.cache.CacheService;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.redisson.api.RMapCache;
|
||||
import org.redisson.api.RedissonClient;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verifyNoInteractions;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* CacheServiceRedisImpl 回归测试。
|
||||
*
|
||||
* 背景:cache.type=redis 时预览单张图片,compressFileKey 为 null,
|
||||
* 修复前会把 null 直接传给 Redisson,抛出 NullPointerException: map key can't be null。
|
||||
*/
|
||||
class CacheServiceRedisImplTests {
|
||||
|
||||
@Test
|
||||
void shouldReturnEmptyListWhenKeyIsNull() {
|
||||
RedissonClient redissonClient = mock(RedissonClient.class);
|
||||
CacheServiceRedisImpl cacheService = new CacheServiceRedisImpl(redissonClient);
|
||||
|
||||
List<String> result = cacheService.getImgCache(null);
|
||||
|
||||
assertNotNull(result);
|
||||
assertTrue(result.isEmpty());
|
||||
// 判空后不应再访问 Redis —— 修复前这里会调用 getMapCache 并抛出 NPE
|
||||
verifyNoInteractions(redissonClient);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldReturnEmptyListWhenKeyIsEmpty() {
|
||||
RedissonClient redissonClient = mock(RedissonClient.class);
|
||||
CacheServiceRedisImpl cacheService = new CacheServiceRedisImpl(redissonClient);
|
||||
|
||||
List<String> result = cacheService.getImgCache("");
|
||||
|
||||
assertNotNull(result);
|
||||
assertTrue(result.isEmpty());
|
||||
verifyNoInteractions(redissonClient);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldReadFromRedisWhenKeyIsPresent() {
|
||||
RedissonClient redissonClient = mock(RedissonClient.class);
|
||||
@SuppressWarnings("unchecked")
|
||||
RMapCache<String, List<String>> mapCache = mock(RMapCache.class);
|
||||
when(redissonClient.<String, List<String>>getMapCache(CacheService.FILE_PREVIEW_IMGS_KEY))
|
||||
.thenReturn(mapCache);
|
||||
when(mapCache.get("zip-key")).thenReturn(List.of("a.png", "b.png"));
|
||||
|
||||
CacheServiceRedisImpl cacheService = new CacheServiceRedisImpl(redissonClient);
|
||||
|
||||
List<String> result = cacheService.getImgCache("zip-key");
|
||||
|
||||
assertEquals(List.of("a.png", "b.png"), result);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user