在我的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中,我只想管理某些字段,其余的留给Jackson来管理。

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?

最佳答案

问题是您将需要一个完全构造的默认解串器;这需要先构建一个,然后您的解串器才能访问它。 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);
  }
}

07-27 18:57