Jackson JSON provides an exception for a collection of a nested class

Jackson JSON has no problems serializing / deserializing this class:

public class MyClass {
   public class Nested {
      public String string;
      public Nested() {}
   }
   public Nested nestedVar;
}

but on this:

public class MyClass {
   class Nested {
      public String string;
      public Nested() {}
   }
   public Nested nestedVar;
   public List<Nested> nestedList;
}

I get this exception when deserializing:

com.fasterxml.jackson.databind.JsonMappingException: no suitable constructor found for type [simple type, class test.MyClass $ Nested]: it is not possible to instantiate from a JSON object (missing default constructor or creator, or you may need to add / include information about type?) in [Source: java.io.StringReader@26653222 ; row: 1, column: 48] (via the chain of links: test.MyClass ["nestedList"] → java.util.ArrayList [0])

In the first case, Jackson has no problems with an instance of a nested class, but not in the second case.

?

(Jackson 2.6.3):

import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;

public class ATest {

   public static void main(String[] args) throws IOException {

      ObjectMapper mapper = new ObjectMapper();

      StringWriter sw = new StringWriter();

      MyClass myClass = new MyClass();

      MyClass.Nested nestedVar = myClass.new Nested();

      List<MyClass.Nested> nestedList = new ArrayList<>();

      nestedList.add(nestedVar);

      myClass.nestedList =nestedList;

      myClass.nestedVar = nestedVar;

      mapper.writeValue(sw, myClass);

      System.out.println(sw.toString());

      StringReader sr = new StringReader(sw.toString());

      MyClass z = mapper.readValue(sr, MyClass.class);
}

}

+4
1

, , bean (BeanDeserializerBase.java 476 2.6.3). , . , , .

, Jackson Nested , , Nested.

, :

    @JsonDeserialize(contentUsing = NestedDeserializer.class)
    public List<Nested> nestedList;

, :

  • , MyClass .

  • / Nested, .

:

public static final class NestedDeserializer extends StdDeserializer<MyClass.Nested>
    implements ResolvableDeserializer {
  private JsonDeserializer<Object> underlyingDeserializer;

  public NestedDeserializer() {
    super(MyClass.Nested.class);
  }

  @Override
  public void resolve(DeserializationContext ctxt) throws JsonMappingException {
    underlyingDeserializer = ctxt
        .findRootValueDeserializer(ctxt.getTypeFactory().constructType(MyClass.Nested.class));
  }

  @Override
  public Nested deserialize(JsonParser p, DeserializationContext ctxt)
      throws IOException, JsonProcessingException {
    JsonStreamContext ourContext = p.getParsingContext();
    JsonStreamContext listContext = ourContext.getParent();
    JsonStreamContext containerContext = listContext.getParent();
    MyClass container = (MyClass) containerContext.getCurrentValue();
    MyClass.Nested value = container.new Nested();
    // note use of three-argument deserialize method to specify instance to populate
    underlyingDeserializer.deserialize(p, ctxt, value);
    return value;
  }
}
+5

Source: https://habr.com/ru/post/1615871/


All Articles