当前位置: 首页 > 知识库问答 >
问题:

如何从Jackson中的自定义反序列化程序调用默认的反序列化程序

上官高翰
2023-03-14

我在Jackson的自定义反序列化程序中有一个问题。我想访问默认序列化程序来填充我要反序列化到的对象。在填充之后,我将执行一些自定义操作,但首先我要使用默认的Jackson行为反序列化对象。

这是我现在有的代码。

public class UserEventDeserializer extends StdDeserializer<User> {

  private static final long serialVersionUID = 7923585097068641765L;

  public UserEventDeserializer() {
    super(User.class);
  }

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

    ObjectCodec oc = jp.getCodec();
    JsonNode node = oc.readTree(jp);
    User deserializedUser = null;
    deserializedUser = super.deserialize(jp, ctxt, new User()); 
    // The previous line generates an exception java.lang.UnsupportedOperationException
    // Because there is no implementation of the deserializer.
    // I want a way to access the default spring deserializer for my User class.
    // How can I do that?

    //Special logic

    return deserializedUser;
  }

}

我需要的是一种初始化默认反序列化器的方法,这样我就可以在开始我的特殊逻辑之前预填充我的POJO。

当从自定义反序列化程序内调用deserialize时,无论我如何构造序列化程序类,该方法似乎都是从当前上下文调用的。因为我的POJO中的注释。由于明显的原因,这会导致堆栈溢出异常。

我尝试过初始化BeandeSerializer,但过程非常复杂,我还没有找到正确的方法。我还尝试过重载AnnotationIntrospector但没有成功,我认为这可能会帮助我忽略DeserializerContext中的注释。最后,我认为我使用jsonDeserializerBuilders可能取得了一些成功,尽管这需要我做一些神奇的事情来从Spring获取应用程序上下文。我将非常感谢任何可以引导我找到更干净的解决方案的东西,例如,如何在不读取JSONDeserializer注释的情况下构造反序列化上下文。

共有1个答案

南宫兴德
2023-03-14

正如StaxMan已经建议的,您可以通过编写BeandeSerializerModifier并通过SimpleModule注册它来实现这一点。下面的示例应该起作用:

public class UserEventDeserializer extends StdDeserializer<User> implements ResolvableDeserializer
{
  private static final long serialVersionUID = 7923585097068641765L;

  private final JsonDeserializer<?> defaultDeserializer;

  public UserEventDeserializer(JsonDeserializer<?> defaultDeserializer)
  {
    super(User.class);
    this.defaultDeserializer = defaultDeserializer;
  }

  @Override public User deserialize(JsonParser jp, DeserializationContext ctxt)
      throws IOException, JsonProcessingException
  {
    User deserializedUser = (User) defaultDeserializer.deserialize(jp, ctxt);

    // Special logic

    return deserializedUser;
  }

  // for some reason you have to implement ResolvableDeserializer when modifying BeanDeserializer
  // otherwise deserializing throws JsonMappingException??
  @Override public void resolve(DeserializationContext ctxt) throws JsonMappingException
  {
    ((ResolvableDeserializer) defaultDeserializer).resolve(ctxt);
  }


  public static void main(String[] args) throws JsonParseException, JsonMappingException, IOException
  {
    SimpleModule module = new SimpleModule();
    module.setDeserializerModifier(new BeanDeserializerModifier()
    {
      @Override public JsonDeserializer<?> modifyDeserializer(DeserializationConfig config, BeanDescription beanDesc, JsonDeserializer<?> deserializer)
      {
        if (beanDesc.getBeanClass() == User.class)
          return new UserEventDeserializer(deserializer);
        return deserializer;
      }
    });


    ObjectMapper mapper = new ObjectMapper();
    mapper.registerModule(module);
    User user = mapper.readValue(new File("test.json"), User.class);
  }
}
 类似资料:
  • 假设我正在为某个类编写自定义序列化,但希望使用默认方法处理其中一个字段。 那要怎么做? 序列化时,我们有。 但反序列化的相应方法是什么? 请注意以下代码: 如何实现MyOuterDeserializer?

  • 我想通过扩展默认的反序列化器来创建自己的反序列化器,在其后面设置更多的值: 如您所见,我还想将此DTO母类重用于其他DTO。 我没有找到任何这样的例子。我真的是世界上第一个 反序列化的“AsUsual”(p,ctxt)应该是什么 我应该使用什么motherclass?JsonDeserializer/StdDeserializer/UntypedObjectDeserializer 反序列化程序会

  • 我想反序列化表单中的类: 其中文本是加密的,反序列化应该在重建TestFieldEncryptedMessage实例之前取消对值的加密。 我采用的方法非常类似于:https://github.com/codesqueak/jackson-json-crypto 也就是说,我正在构建一个扩展SimpleModule的模块: 如您所见,设置了两个修饰符:EncryptedSerializerModif

  • 我有一个Spring项目,我尝试添加一个自定义反序列化器来反序列化日期属性,具体取决于它们的格式。如果我将其用作Date属性的注释,则效果很好。但是,如果我将反序列化器添加到对象映射器中,当Jackson反序列化日期时,它不会调用。 我尝试这样应用我的自定义反序列化程序: 我不想每次都对Date属性应用注释,我想默认使用此反序列化器。我做错了什么?

  • 我想创建一个自定义序列化程序,它只做一点点工作,然后将其余部分留给默认序列化。 例如: 通过为聚合对象创建其他自定义序列化器的想法,这些对象根据“特殊”属性值表现不同。然而,上面的代码不起作用,因为它毫不奇怪地进入了无限递归。 一旦我设置了属性,有没有办法告诉jackson使用默认序列化?我真的不想像许多自定义序列化程序那样枚举所有属性,因为该类相当复杂,并且我不想每次更改该类时都必须对序列化程序

  • 情况如下:我已经设法让Jackson反序列化以下通用 作为HTTP客户端,并使用exchange