用jackson排除自定义反序列化器

时间:2015-08-18 16:06:26

标签: java jackson deserialization

在我的pojo类中,我已经使用注释

配置了CustomDeserializer
@JsonDeserialize(using = CustomDeserializer.class)
class Myclass {
     private String A;
     @JsonIgnore
     private String B;
     @JsonIgnore
     private String C;
     private String D;
     ...
     private String Z;

     /*getters and setters*/
}

CustomDeserializer中,我只想管理其中一些字段,剩下的就让杰克逊管理。

CustomDeserializer.java

public class CustomDeserializer extends StdDeserializer<Myclass > {

    private static final long serialVersionUID = 4781685606089836048L;

    public CustomDeserializer() {
        super(Myclass.class);
    }

    @Override
    public Myclass deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, IllegalResponseException {

        ObjectMapper mapper = (ObjectMapper) jp.getCodec();
        ObjectNode root = (ObjectNode) mapper.readTree(jp);

        Myclass myClass =  mapper.readValue(root.toString(), Myclass.class);

        //--- HERE MANAGE FIELD B ---
        myClass.setB(myNewB);
        //--- HERE MANAGE FIELD C ---
        myClass.setC(myNewC);

        return myClass;
    }
}

这样我就会因为以下行而遇到无限循环:

mapper.readValue(root.toString(), Myclass.class);

有没有办法在使用Jackson时设置默认行为,以便我可以排除我的CustomDeserializer?

1 个答案:

答案 0 :(得分:1)

问题是你需要一个完全构造的默认解串器;这需要一个构建,然后你的反序列化器可以访问它。 DeserializationContext不是你应该创造或改变的东西;它将由ObjectMapper提供。

要满足您的要求,您可以先撰写BeanDeserializerModifier并通过SimpleModule注册。

以下示例应该有效:

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

  private final JsonDeserializer<?> defaultDeserializer;

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

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

    // custom logic

    return deserializedMyclass;
  }

  // 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();
    //Writing a new BeanDeserializerModifier 
    module.setDeserializerModifier(new BeanDeserializerModifier()
    {
      @Override public JsonDeserializer<?> modifyDeserializer(DeserializationConfig config, BeanDescription beanDesc, JsonDeserializer<?> deserializer)
      {
        if (beanDesc.getBeanClass() == Myclass.class)
          return new CustomDeserializer(deserializer);
        return deserializer;
      }
    });

    //register the BeanDeserializerModifier via SimpleModule
    ObjectMapper mapper = new ObjectMapper();
    mapper.registerModule(module);
    Myclass myclass = mapper.readValue(new File("d:\\test.json"), Myclass.class);
  }
}