2016-11-25 3 views
1

Есть несколько аналогичных вопросов here и here, но они не совсем соответствуют моей ситуации. Моя JSON строка состоит из объекта с массивом:Jackson ObjectMapper десериализует объект с массивом

{ 
    "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" 
    } 
    ] 
} 

Каждый объект в массиве является Java боб:

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 
    // ... 
} 

Я могу читать один TrainingInfo с:

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

Но я не могу прочитать весь массив. Я попытался создать новый Java-компонент просто containng массив и читать, например, так:

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

Но это просто бросает IOException. Что мне не хватает?

UPDATE: Исключение брошено:

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) 
+0

Не могли бы вы включить «IOException»? –

+1

Я думаю, потому что вы определили его как частный класс. –

+3

Сделайте свой класс TrainingsArray классом верхнего уровня или, по крайней мере, статическим вложенным классом вместо внутреннего класса. Внутреннему классу требуется ссылка на его внешний экземпляр, который должен быть сконструирован. Джексону пришлось бы создать экземпляр JsonMapperTest. И он этого не сделает. –

ответ

1

Однако глупо это может быть, решение было сделать класс TrainingsArray общественности.

Смежные вопросы