如何从 Jackson 中的自定义解串器调用默认解串器 [英] How do I call the default deserializer from a custom deserializer in Jackson

查看:29
本文介绍了如何从 Jackson 中的自定义解串器调用默认解串器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 Jackson 中的自定义解串器有问题.我想访问默认序列化程序来填充我要反序列化的对象.在填充之后,我会做一些自定义的事情,但首先我想用默认的 Jackson 行为反序列化对象.

I have a problem in my custom deserializer in Jackson. I want to access the default serializer to populate the object I am deserializing into. After the population I will do some custom things but first I want to deserialize the object with the default Jackson behavior.

这是我目前拥有的代码.

This is the code that I have at the moment.

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.

What I need is a way to initialize the default deserializer so that I can pre-populate my POJO before I start my special logic.

从自定义反序列化器中调用反序列化时无论我如何构造序列化器类,似乎该方法都是从当前上下文调用的.因为我的 POJO 中有注释.由于显而易见的原因,这会导致 Stack Overflow 异常.

When calling deserialize from within the custom deserializer It seems the method is called from the current context no matter how I construct the serializer class. Because of the annotation in my POJO. This causes a Stack Overflow exception for obvious reasons.

我曾尝试初始化一个 BeanDeserializer,但该过程极其复杂,而且我还没有找到正确的方法.我也尝试过重载 AnnotationIntrospector 无济于事,认为它可能会帮助我忽略 DeserializerContext 中的注释.最后,我可能已经使用 JsonDeserializerBuilders 取得了一些成功,尽管这需要我做一些神奇的事情来从 Spring 获取应用程序上下文.我很感激任何可以引导我找到更清晰解决方案的事情,例如如何在不阅读 JsonDeserializer 注释的情况下构建反序列化上下文.

I have tried initializing a BeanDeserializer but the process is extremely complex and I haven't managed to find the right way to do it. I have also tried overloading the AnnotationIntrospector to no avail, thinking that it might help me ignore the annotation in the DeserializerContext. Finally it seams I might have had some success using JsonDeserializerBuilders although this required me to do some magic stuff to get hold of the application context from Spring. I would appreciate any thing that could lead me to a cleaner solution for example how Can I construct a deserialization context without reading the JsonDeserializer annotation.

推荐答案

正如 StaxMan 已经建议的那样,您可以通过编写一个 BeanDeserializerModifier 并通过 SimpleModule 注册它来做到这一点.以下示例应该可以工作:

As StaxMan already suggested you can do this by writing a BeanDeserializerModifier and registering it via SimpleModule. The following example should work:

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

这篇关于如何从 Jackson 中的自定义解串器调用默认解串器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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