一个杰克逊解串器用于多种类型(通过注释配置)

时间:2012-09-07 12:28:24

标签: json jackson deserialization

我正在尝试更改其中一个类中列表的(反)序列化。

列表中的对象应序列化为int(它们的jpa id)并相应地反序列化。序列化很简单。

对于反序列化我有一个类,如果id和class已知,它可以将id转换为对象。

我如何从杰克逊那里获得必要的课程?所有默认的jackson序列化程序都有这样的构造函数:protected StdDeserialiser(Class<?> vc)所以信息存在于某处。

有没有办法在反序列化期间访问它? 或者在杰克逊建造解串器之前? 或者在HandlerInstantiator内?

我只想覆盖某些引用的默认deseriliser,所以我不能只写一个提供者或自定义模块。

2 个答案:

答案 0 :(得分:1)

我在ContextDeserializer接口的帮助下从反序列化器内部工作,因为它为反序列化器提供了目标属性。

public JsonDeserializer<?> createContextual(DeserializationContext ctxt, BeanProperty property) throws JsonMappingException {
    Class<?> vc = null;
    if (property.getType().isCollectionLikeType()) {
        vc = property.getType().getContentType().getRawClass();
    } else {
        vc = property.getType().getRawClass();
    }
    return new ResourcePathDeserializer(vc, converter);
}

这个解决方案并不完美,因为我只获取返回类型的原始类或泛型(可能是父类或接口),但这足以满足我的要求。 如果我可以访问由杰克逊解决的“真正的”课程会更好,但对我来说这是有效的。

答案 1 :(得分:0)

首先,编写模块没什么好看的:它只是插入内容的一种方式,比如自定义(反)序列化器。所以没必要避免这种情况。而你最需要编写一个模块来做你想做的事。

一般来说,尝试创建“通用”序列化器或反序列化器并不是一个好主意,它可能会遇到问题。但这取决于你究竟想要做什么。

类型信息可以是:

  • 从上下文隐含:您正在为类型T编写(de)序列化程序,并为其注册,因此这是您的类型
  • 当正在构建(de)序列化程序时,通过Module接口传递Jackson:模块被询问他们是否碰巧有类型T的(de)序列化器。SimpleModule将只使用基本类-to-impl mapping(这就是“简单”来自的地方);但完全自定义Module可以访问传入类型。

但我不知道上述内容是否适用于您的用例。类型信息必须是静态类型(列表的声明内容类型)。