Closed leonchen83 closed 2 years ago
我也遇到了相同的问题: os:windows 11 jdk:jdk 11 jar:fastjson 2.0.11
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.annotation.JSONField;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class EnumCustomTest {
@Test
public void test() {
Bean bean = new Bean();
bean.size = Size.Large;
String str = JSON.toJSONString(bean);
assertEquals("{\"size\":101}", str);
Bean bean1 = JSON.parseObject(str, Bean.class);
assertEquals(bean.size, bean1.size);
}
public static class Bean {
public Size size;
}
public interface XEnum {
@JSONField(value = true)
int getValue();
}
public enum Size implements XEnum {
Small(99),
Medium(100),
Large(101),
XLarge(102);
private final int value;
Size(int value) {
this.value = value;
}
@Override
public int getValue() {
return value;
}
}
}
如果XEnum这个类是在第三方类库中,不能修改,使用Mixin ( https://github.com/alibaba/fastjson2/blob/main/docs/mixin_cn.md ),比如:
public interface XEnumMixin {
@JSONField(value = true)
int getValue();
}
JSON.mixIn(XEnum.class, XEnumMixin.class);
@leonchen83 看下上面这个是不是你想要的。Enum类型支持通过配置@JSONField(value=true)指定序列化用的字段,反序列化也会自动识别这个字段。
支持在interface上配置JSONField,需要用最新的快照版本 https://oss.sonatype.org/content/repositories/snapshots/com/alibaba/fastjson2/fastjson2/2.0.12-SNAPSHOT/
2.0.12预计在8月21日前发布
@wenshao 我们需要为数百个特殊的Enum类做一个序列化与反序列化器,而且不能加JSONField属性,希望fastjson2提供一个入口可以定制自己的Enum序列化与反序列化器,我的理解应该在getObjectReader
, getObjectWriter
这里扩展就好,不过现实是并不生效
@leonchen83 可以统一配置在PersistentEnum#getValue方法上
public interface PersistentEnum<T> {
@JSONField(value = true)
T getValue();
@wenshao
是这样的。我们不仅仅有一个json序列化器与反序列化器,我们同时有jackson和fastjson。不能把fastjson的@JSONField(value = true)
放到PersistentEnum#getValue
上,这样代码中就强依赖fastjson的部分注解了。所以我们一般通过编码的方式来做这件事,既不强依赖jackson也不强依赖fastjson
比如说在jackson中,我们是这样扩展的
public class SimpleDeserializersEx extends SimpleDeserializers {
//
private final ObjectMappers mapper;
private final JsonDeserializer<?> bitwise;
private final JsonDeserializer<?> persistent;
private static final long serialVersionUID = 1L;
/**
*
*/
public SimpleDeserializersEx(ObjectMappers mapper) {
this.mapper = mapper;
bitwise = new BitwiseEnumDeserializer<>();
persistent = new PersistentEnumDeserializer<>();
}
/**
*
*/
@Override
public JsonDeserializer<?> findEnumDeserializer (Class<?> t, DeserializationConfig c, BeanDescription bean)
throws JsonMappingException {
boolean persistent = this.mapper.isPersistentEnumEnabled() && PersistentEnum.class.isAssignableFrom(t);
if(persistent) return this.persistent; else return super.findEnumDeserializer(t, c, bean);/* default */
}
@Override
public JsonDeserializer<?> findBeanDeserializer (JavaType t, DeserializationConfig c, BeanDescription bean)
throws JsonMappingException {
boolean bitwise = mapper.isBitwiseEnumEnabled() && BitwiseEnum.class.isAssignableFrom(t.getRawClass());
if (bitwise) { return this.bitwise; } else return super.findBeanDeserializer(t, c, bean); /* default */
}
}
public class SimpleSerializersEx extends SimpleSerializers {
//
private final ObjectMappers mapper;
private BitwiseEnumSerializer bitwise;
private PersistentEnumSerializer persistent;
private static final long serialVersionUID = 1L;
/**
*
*/
public SimpleSerializersEx ( ObjectMappers mapper ) {
this.mapper = mapper;
this.bitwise = new BitwiseEnumSerializer();
this.persistent = new PersistentEnumSerializer();
}
/**
*
*/
@Override
public JsonSerializer<?> findSerializer ( SerializationConfig config, JavaType type, BeanDescription desc ) {
final Class<?> v = type.getRawClass();
if (mapper.isPersistentEnumEnabled() && PersistentEnum.class.isAssignableFrom(v)) return this.persistent;
else if(this.mapper.isBitwiseEnumEnabled() && BitwiseEnum.class.isAssignableFrom(v)) return this.bitwise;
else return super.findSerializer(config, type, desc);
}
}
声明一个PersistentEnum对应的Mixin类:
public interface PersistentEnumMixin {
@JSONField(value = true)
T getValue();
}
注册Mixin
JSON.mixIn(PersistentEnum.class, PersistentEnumMixin.class);
通过这种方法,也使得代码不直接依赖fastjson,这样的自定义逻辑更简洁
@wenshao 这种方式应该可以,但是我很奇怪为啥
public class XWriterProvider extends ObjectWriterProvider {
@Override
public ObjectWriter getObjectWriter(Type objectType, Class objectClass, boolean fieldBased) {
final boolean persistent = Misc.PersistentEnum.class.isAssignableFrom(objectClass);
if (persistent) return new PersistentEnumSerializer();
else return super.getObjectWriter(objectType, objectClass, fieldBased);
}
}
这个处理找不到对应的Enum序列化器
问题描述
简要描述您碰到的问题。
环境信息
请填写以下信息:
重现步骤
如何操作可以重现该问题:
main.class
misc.class
序列化时期待如下结果
实际
期待的正确结果
对您期望发生的结果进行清晰简洁的描述。
相关日志输出
请复制并粘贴任何相关的日志输出。
附加信息
如果你还有其他需要提供的信息,可以在这里填写(可以提供截图、视频等)。