如何创建一个通用的JsonDeserializer [英] How to create a general JsonDeserializer

查看:3508
本文介绍了如何创建一个通用的JsonDeserializer的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要创建一个通用的解串器;换句话说,我不知道反序列化的目标类是什么。

I need to create a general deserializer; in other words I don't know what the deserialised target class will be.

我在互联网上看过他们创建反序列化器的示例,例如 JsonDeserializer< Customer> 然后在结尾处返回新客户(...)。问题是我不知道返回类是什么。

I have seen examples on the internet where by they create a deserializer such as JsonDeserializer<Customer> and then return a new Customer(...) at the end. The problem is that I don't know what the return class will be.

我想我需要使用反射来创建类的实例并填充字段。我如何从反序列化方法中做到这一点?

I imagine I will need to use reflection to create an instance of the class and populate the field. How can I do it from the deserialize method?

public class JsonApiDeserializer extends JsonDeserializer<Object> {

    @Override
    public Object deserialize(JsonParser jp, DeserializationContext ctxt)
            throws IOException, JsonProcessingException {

        //Need to parse the JSON and return a new instance here
    }

}


推荐答案

经过一些测试,我发现@jax的答案有问题。

After some tests, I find @jax 's answer has a problem.

正如@Staxman所指出的那样,在构造反序列化程序期间调用createContextual(),而不是在每个反序列化过程中调用。由 createContextual 返回的反序列化器将由Jackson库缓存。因此,如果您的反序列化器使用多于一种类型(例如公共父类型的子类型),它将抛出类型不匹配异常,因为targetClass属性将是Jackson库缓存的最后一种类型。

As @Staxman pointed out, createContextual() is called during construction of Deserializer, not in every process of deserialization. And the deserializer returned by createContextual will be cached by the Jackson library. So if your deserializer is used with more than 1 type(such as sub types of a common parent), it will throw out type mismatch exception, cause the targetClass property will be the last type cached by the Jackson library.

正确的解决方案应该是:

The correct solution should be:

public class JsonApiDeserializer extends JsonDeserializer<Object> implements
        ContextualDeserializer {

    private Class<?> targetClass;

    public JsonApiDeserializer() {
    }

    public JsonApiDeserializer(Class<?> targetClass) {
        this.targetClass = targetClass;
    }

    @Override
    public Object deserialize(JsonParser p, DeserializationContext ctxt)
            throws IOException, JsonProcessingException {
        Object clazz = targetClass.newInstance();
        //Now I have an instance of the annotated class I can populate the fields via reflection
        return clazz;
    }

    @Override
    public JsonDeserializer<?> createContextual(DeserializationContext ctxt,
            BeanProperty property) throws JsonMappingException {
        //gets the class type of the annotated class
        targetClass = ctxt.getContextualType().getRawClass();
        //this new JsonApiDeserializer will be cached
        return new JsonApiDeserializer(targetClass);
    }
}

这篇关于如何创建一个通用的JsonDeserializer的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆