1

There are some similar questions here and here, but they don't quite match my situation. My JSON string consists of an object with an array:

{
  "data": [
    {
      "id": 1,
      "title": "Sample training",
      "date": "2016-10-03 10:00:00",
      "subscription": "2016-09-20 12:34:50"
    },
    {
      "id": 2,
      "title": "Second training",
      "date": "2016-10-06 10:00:00",
      "subscription": "2016-09-20 12:54:50"
    }
  ]
}

Each object in the array is a Java bean:

public class TrainingInfo {

    private int id;
    private String title;
    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime date;
    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime subscription;

    // Consructors, getters and setters omitted 
    // ...
}

I am able to read a single TrainingInfo with:

ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JavaTimeModule());
TrainingInfo training = mapper.readValue(jsonTrainingInfo, TrainingInfo.class);

But I am not able to read the whole array. I have tried to create a new Java bean just containng an array and read it, like so:

private class TrainingsArray {
    private TrainingInfo[] data;

    public TrainingInfo[] getData() {
        return data;
    }

    public void setData(TrainingInfo[] data) {
        this.data = data;
    }
}

ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JavaTimeModule());
TrainingsArray trainings = mapper.readValue(jsonTrainingsArray, TrainingsArray.class);

But this just throws an IOException. What am I missing?

UPDATE: The exception thrown:

com.fasterxml.jackson.databind.JsonMappingException: Can not construct instance of JsonMapperTest$TrainingsArray: no suitable constructor found, can not deserialize from Object value (missing default constructor or creator, or perhaps need to add/enable type information?)
 at [Source: {
  "data": [
    {
      "id": 1,
      "title": "Sample training",
      "date": "2016-10-03 10:00:00",
      "subscription": "2016-09-20 12:34:50"
    },
    {
      "id": 2,
      "title": "Second training",
      "date": "2016-10-06 10:00:00",
      "subscription": "2016-09-20 12:54:50"
    }
  ]
}; line: 2, column: 3]

    at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:270)
    at com.fasterxml.jackson.databind.DeserializationContext.instantiationException(DeserializationContext.java:1456)
    at com.fasterxml.jackson.databind.DeserializationContext.handleMissingInstantiator(DeserializationContext.java:1012)
    at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromObjectUsingNonDefault(BeanDeserializerBase.java:1205)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:314)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:148)
    at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:3798)
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2842)
    at JsonMapperTest.shouldMapJsonResponseToTrainingsArray(JsonMapperTest.java:90)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:157)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
    at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:51)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:237)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
8
  • Could you please include the IOException? Commented Nov 25, 2016 at 9:46
  • 1
    I think because you've defined it as a private class. Commented Nov 25, 2016 at 9:52
  • 3
    Make your TrainingsArray class a top-level class, or at least a static nested class instead of an inner class. An inner class needs a reference to its outer instance to be constructed. Jackson would have to create an instance of JsonMapperTest. And it won't do that. Commented Nov 25, 2016 at 9:54
  • 1
    make your class TrainingsArray accessible by making it public instead of private, if you want to keep it as an inner class make it static too Commented Nov 25, 2016 at 10:01
  • JB and Nicolas are correct, inner class may be a problem as well, I assumed it was a normal class... Commented Nov 25, 2016 at 10:09

1 Answer 1

1

However silly this might be, the solution was to make the class TrainingsArray public.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.