[alibaba/fastjson]@JSONField 的 deserializeUsing 不起作用?

2025-11-11 686 views
9

用下面的代码测试,发现并没有调用 @JSONField 注解上 deserializeUsing 指定的 ModelValueDeserializer 类? 版本 1.2.25, 1.2.32 以及最新的 1.2.43 都有问题

public class Main2 {

    public static void main(String[] args) {
        //ParserConfig.getGlobalInstance().putDeserializer(Model.class, new ModelValueDeserializer());
        String json = "{\"value\":123}";
        Model model = JSON.parseObject(json, Model.class);
        System.out.println(JSON.toJSONString(model));
    }

    public static class Model {
        @JSONField(serializeUsing = ModelValueSerializer.class, deserializeUsing = ModelValueDeserializer.class)
        public int value;
    }

    public static class ModelValueSerializer implements ObjectSerializer {
        @Override
        public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType,
                          int features) throws IOException {
            Integer value = (Integer) object;
            String text = value + "元";
            serializer.write(text);
        }
    }

    public static class ModelValueDeserializer implements ObjectDeserializer {

        @Override
        public Integer deserialze(DefaultJSONParser parser, Type type, Object fieldName) {
            return parser.getLexer().intValue() * 100;
        }

        @Override
        public int getFastMatchToken() {
            return 0;
        }
    }
}

回答

3

自定义反序列化的使用有误,可以这样:


 public Model deserialze(DefaultJSONParser parser, Type type, Object fieldName) {
            JSONObject obj = (JSONObject)parser.parse();
            Model model = new Model();
            model.value = obj.getInteger("value") * 100;
            return model;
        }
7

testcase:https://github.com/alibaba/fastjson/pull/1664

另外,你注册的类型是putDeserializer(Model.class, new ModelValueDeserializer()); 那么,fastjson会直接拿这个自定义的deserialze的方法结果作为Model的实例,而不是里面的value, 同时,由于你定义了全局反序列化,导致这个deserialze里也不能用parseObject之类的操作了, 只能new一个model出来,再返回给调用方。

8

如果真需要这样用,多麻烦啊,而且完全耦合了目标对象,@JSONField deserializeUsing 就有点鸡肋了吧,作者初衷应该不是这样的吧

5

@kimmking 这行代码我是注释掉的,并没有使用: //ParserConfig.getGlobalInstance().putDeserializer(Model.class, new ModelValueDeserializer());

我是期望能通过 Deserializer 对 field 产生自定义反序列化作用,可能会对同一个对象上多个 field 指定自定义 Deserializer

7

后来解决了吗? +1

5

为什么会有这样的需求?

9

举个例子,我想在反序列化的时候,解密某些字段,或者其它加工处理。

public class Config
{
    @JSONField(name ="jdbc.password", deserializeUsing=DecryptDeserializer.class)
    private String password

}

就像jackson的 com.fasterxml.jackson.databind.annotation.JsonDeserializer

3

还是不好用,单纯针对某个属性的反序列化,用的版本为1.2.49, @wenshao

1

a

9

恩 我也遇到了问题 , 请问后来解决了吗

1

我是这样的用法 , 连自定义反序列化器的断点都没有走到

6

I had the same problem,

2

我是这样的用法 , 连自定义反序列化器的断点都没有走到

同没走到自定义反序列化器