1

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

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

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

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

有没有办法在反序列化期间访问它?还是在杰克逊构造解串器之前?还是在 HandlerInstantiator 内部?

我只想覆盖某些引用的默认解串器,所以我不能只编写提供程序或自定义模块。

4

2 回答 2

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);
}

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

于 2012-09-11T09:49:04.607 回答
0

首先,编写模块没有什么花哨的:它只是一种插入东西的方式,比如自定义(反)序列化器。所以没有必要避免这种情况。你最喜欢写一个模块来做你想做的事。

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

类型信息将是:

  • 从上下文中隐含:您正在为类型 T 编写(反)序列化程序,并为它注册它,所以这就是您的类型
  • Jackson 在构造(反)序列化器时通过Module接口传递:询问模块是否碰巧有类型 T 的(反)序列化器。SimpleModule将仅使用基本的类到实现的映射(这就是“简单”的来源); 但完全自定义Module可以访问传入类型。

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

于 2012-09-07T19:54:09.053 回答