feat(cache): 值编解码器(fastjson 序列化 + 空值标记)
This commit is contained in:
37
src/main/java/com/njcn/middle/cache/support/CacheValueCodec.java
vendored
Normal file
37
src/main/java/com/njcn/middle/cache/support/CacheValueCodec.java
vendored
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
package com.njcn.middle.cache.support;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import com.alibaba.fastjson.TypeReference;
|
||||||
|
import com.njcn.middle.cache.constant.CacheConstant;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 缓存值编解码:对象 ↔ 字符串(fastjson),并承载空值标记。
|
||||||
|
*
|
||||||
|
* <p>解码失败直接抛 fastjson 异常({@link RuntimeException}),由调用方决定显式暴露(public get)
|
||||||
|
* 还是当未命中降级(getOrLoad 内部)。
|
||||||
|
*/
|
||||||
|
public class CacheValueCodec {
|
||||||
|
|
||||||
|
/** 对象 → 字符串:null → 空值标记;否则 fastjson 序列化。 */
|
||||||
|
public String encode(Object value) {
|
||||||
|
if (value == null) {
|
||||||
|
return CacheConstant.NULL_SENTINEL;
|
||||||
|
}
|
||||||
|
return JSON.toJSONString(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 是否空值标记。 */
|
||||||
|
public boolean isNullSentinel(String raw) {
|
||||||
|
return CacheConstant.NULL_SENTINEL.equals(raw);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 字符串 → 对象(Class)。 */
|
||||||
|
public <T> T decode(String raw, Class<T> type) {
|
||||||
|
return JSON.parseObject(raw, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 字符串 → 对象(TypeReference,支持泛型)。 */
|
||||||
|
public <T> T decode(String raw, TypeReference<T> type) {
|
||||||
|
return JSON.parseObject(raw, type);
|
||||||
|
}
|
||||||
|
}
|
||||||
64
src/test/java/com/njcn/middle/cache/support/CacheValueCodecTest.java
vendored
Normal file
64
src/test/java/com/njcn/middle/cache/support/CacheValueCodecTest.java
vendored
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
package com.njcn.middle.cache.support;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.TypeReference;
|
||||||
|
import com.njcn.middle.cache.constant.CacheConstant;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
|
class CacheValueCodecTest {
|
||||||
|
|
||||||
|
private final CacheValueCodec codec = new CacheValueCodec();
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
static class Foo {
|
||||||
|
private Long id;
|
||||||
|
private String name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void encodeNullReturnsSentinel() {
|
||||||
|
assertEquals(CacheConstant.NULL_SENTINEL, codec.encode(null));
|
||||||
|
assertTrue(codec.isNullSentinel(codec.encode(null)));
|
||||||
|
assertFalse(codec.isNullSentinel("{\"id\":1}"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void encodeDecodePojoRoundTrip() {
|
||||||
|
Foo foo = new Foo(1L, "alice");
|
||||||
|
String raw = codec.encode(foo);
|
||||||
|
Foo back = codec.decode(raw, Foo.class);
|
||||||
|
assertEquals(foo, back);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void encodeDecodeStringRoundTrip() {
|
||||||
|
String raw = codec.encode("abc");
|
||||||
|
assertEquals("abc", codec.decode(raw, String.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void decodeGenericWithTypeReference() {
|
||||||
|
List<Integer> list = Arrays.asList(1, 2, 3);
|
||||||
|
String raw = codec.encode(list);
|
||||||
|
List<Integer> back = codec.decode(raw, new TypeReference<List<Integer>>() {
|
||||||
|
});
|
||||||
|
assertEquals(list, back);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void decodeDirtyStringThrows() {
|
||||||
|
assertThrows(RuntimeException.class, () -> codec.decode("{not-json", Foo.class));
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user