对实现了特定接口的枚举进行统一序列化和反序列化[FEATURE]
- Dominant language
- Java
- Stars
- 4.4k
- Forks
- 613
- Avg merge
- 1d 22h
- Merged PRs (30d)
- 6
Description
### 请描述您的需求或者改进建议
*对您想要需求或建议的清晰简洁的描述。*
一般项目中,我会定义一个规范枚举的接口,例如如下:
```java
public interface FierceEnum extends IEnum {
/**
* 获取枚举值名称
*
* @return 名称
*/
String getName();
/**
* 获取枚举值描述
*
* @return 描述
*/
default String getDescription() {
return null;
}
/**
* 获取指定值枚举项
*
* @param clazz 枚举类
* @param value 枚举值
* @param 枚举类型
* @return 枚举项对象
*/
static T getEnum(final Class clazz, final Integer value) {
if (clazz.isEnum() && FierceEnum.class.isAssignableFrom(clazz)) {
final T[] constants = clazz.getEnumConstants();
for (T constant : constants) {
final FierceEnum item = (FierceEnum) constant;
if (item.getValue().equals(value)) {
return constant;
}
}
}
// 找不到或者不是枚举类,则返回null
return null;
}
}
```
那么假设项目中存在一个枚举类,叫 `SwitchStatus`:
```java
@Getter
@RequiredArgsConstructor
public enum SwitchStatus implements FierceEnum {
/**
* 启用
*/
ENABLED("启用", 1),
/**
* 停用
*/
DISABLED("停用", 2);
/**
* 名称
*/
private final String name;
/**
* 值
*/
private final Integer value;
}
```
从上可见,项目中约定所有枚举必须统一实现 `FierceEnum` 接口,规范枚举的属性。那么项目中其实还有若干类似枚举类定义。
现在问题来了,项目统一使用 `FastJson2` 这个牛逼哄哄的JSON序列化反序列化框架,我希望我需要做的就是自定义一个序列化器和一个反序列化器来统一实现对项目中这个 `FierceEnum` 的序列化和反序列化。
**比较遗憾的是,目前fastjson2 只能通过注册一个具体特定的枚举类进行自定义的序列化和反序列化,拿上面这个 `SwitchStatus` 来举例:**
```java
JSON.register(
FierceEnum.class,
new ObjectWriter() {
@Override
public void write(JSONWriter jsonWriter, Object object, Object fieldName, Type fieldType, long features) {
jsonWriter.writeInt32(
((FierceEnum)object).getValue()
);
}
}
);
JSON.register(
FierceEnum.class,
new ObjectReader() {
@Override
public UserType readObject(JSONReader jsonReader, Type fieldType, Object fieldName, long features) {
return FierceEnum.getEnum(UserType.class, jsonReader.readInt32());
}
}
);
```
可以看到,如果我有100个枚举类,我这里就要注册200个序列化及反序列化器实现,这不是有点让人蛋疼,虽然我目前可以通过类似Spring的组件扫描机制来实现自动扫描包下所有的枚举类来自动注册,但是我觉得这步实在是没有必要,不知道大佬们怎么看?
我对FastJson2的代码吐槽如下几点😂(我可能也只是个菜鸟,但我希望这个库可以做到更好):
* 1、ObjectReader 和 ObjectWriter 接口为啥没注释?是因为太简单了懒得注释吗?作为有强迫症的程序员,我十分希望项目可以保持风格统一,至少方法和参数的注释必须要有
* 2、ObjectReader 和 ObjectWriter 的泛型是摆设吗?你既然定义泛型,为啥方法参数类型不用呢?
* 3、ObjectReader 和 ObjectWriter 的 readObject 和 write 方法中的一个参数 fieldName,字段名称?不应该是 String 类型吗?为啥要定义成 Object 类型,可能是我见识浅薄,没领悟到其中的奥妙,希望可以指点我一点
### 请描述你建议的实现方案
*对您想要需求或建议的实现方案的详细描述。*
这里我简单叙述一下我的想法吧,我用伪代码实现:
```java
JSON.register(
FierceEnum.class,
new ObjectWriter() {
@Override
public void write(JSONWriter jsonWriter, FierceEnum value, String fieldName, Type fieldType, long features) {
jsonWriter.writeInt32(
value.getValue()
);
}
}
);
JSON.register(
FierceEnum.class,
new ObjectReader() {
@Override
public UserType readObject(JSONReader jsonReader, Type fieldType, String fieldName, long features) {
return FierceEnum.getEnum((Class) fieldType, jsonReader.readInt32());
}
}
);
```
上面中我直接连方法签名都改了,如果觉得我的建议不错,希望可以采纳。我简单叙述一下,上面的代码我希望实现的是,就靠这两个序列化和反序列化器就可以实现我项目中所有的 FierceEnum 枚举类的 序列化和反序列化。
但是目前可惜的是,fastjson2可能在选择序列化器或反序列化器的时候对类型的判断应该是全等判断,例如:`a.class.equals(b.class)`,当然,具体源码我也没读过,不知道嘞。
我建议可以采用类似伪代码:`serializer/desrializer.getSupportedType().isAssignableFrom(pojoField.getType())` 来判断,尽可能的可以通过父类解决处理衍生子类的序列化和反序列化问题,减少序列化器和反序列化器的自定义实现,一劳永逸。
当然框架之所以这么做可能也有其内在的原因,我也不懂,如果可以这么搞,希望可以尽可能的这么搞。以上是我的一些浅薄之见,欢迎大佬指点,非常感谢!!!
### 描述您考虑过的替代方案
*对您考虑过的任何替代解决方案或功能的描述。*
使用ClassPathScanner 进行扫描项目包下所有的枚举类,自动创建序列化和反序列化器,虽然解决了手动创建的烦恼,但是我总觉得不够优雅,明明两个序列化和反序列化器就能解决的问题,非得我自定义成百上千,有点难受(尽管是自动生成的)
#### 附加信息
*如果你还有其他需要提供的信息,可以在这里填写(可以提供截图、视频等)。*
最后,再建议一点,既然序列化和反序列化接口都有了泛型,那么在注册其具体实现的时候,我觉的也可以不用再指定一个Class来表明序列化器对那个类型生效,直接写一个类似Spring中的 `ResolvableType` 解析泛型类型得到这个 Class
Contributor guide
Research direction
The request centers on JSON.register and the ObjectReader/ObjectWriter interfaces; start by tracing how FastJson2 selects registered readers and writers for enum and interface types. No file or test is named in the issue; done would mean one registration can serialize and deserialize all enums implementing the requested interface without per-class registrations.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- backend-api-design
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 30/100