I have a problem when trying to useorg.codehaus.jackson.map.ObjectMapper.readValue(String content, Class<NestedObject> valueType)
.
The scenario is as follows: I have a NestedObject
class which has a member of class Container
. The Container
class has a member which is a java.util.List
for a type AbstractNestedObject
. I use this abstract class because the List in the Container
class may either contain an object from a class Item
or again an object from class Container
and I need to traverse the list and save the respective content.
The object structure serves to map a JSON string to my Java object. My problem is, that when I try to deserialize the JSON string, I get the following exception:
org.codehaus.jackson.map.JsonMappingException: Can not construct instance of src.AbstractNestedObject, problem: abstract types can only be instantiated with additional type information
I have read about Annotations but these don't seem to solve my problem because my JSON String does not have any 'type' or 'name'.
Maybe someone can help me on this? Here are my classes:
The NestedObject:
public class NestedObject {
private Container container;
public NestedObject() {
}
public NestedObject(Container Container) {
this.setContainer(container);
}
public Container getContainer() {
return container;
}
public void setContainer(Container container) {
this.container = container;
}
}
The abstract class:
public abstract class AbstractNestedObject {
private ObjectType objectType;
public AbstractNestedObject() {
}
public AbstractNestedObject(ObjectType objectType){
this.objectType = objectType;
}
public ObjectType getObjectType() {
return objectType;
}
}
An Enum for the two object types:
public enum ObjectType {
CONTAINER,
ITEM;
}
The Container class:
import java.util.List;
public class Container extends AbstractNestedObject {
private String containerProperty;
public List<AbstractNestedObject> items;
public String getContainerProperty() {
return containerProperty;
}
public void setContainerProperty(String containerProperty) {
this.containerProperty = containerProperty;
}
public List<AbstractNestedObject> getItems() {
return items;
}
public void setItems(List<AbstractNestedObject> items) {
this.items = items;
}
}
The Item class:
public class Item extends AbstractNestedObject {
private String color;
private String shape;
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public String getShape() {
return shape;
}
public void setShape(String shape) {
this.shape = shape;
}
}
A Test class:
import java.io.IOException;
import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;
public class Test {
public static void main(String[] args) {
String json = "{ \"container\": { \"containerProperty\": \"red\", \"items\": [ {\"color\": \"white\",\"shape\": \"round\"},{\"container\": {\"containerProperty\": \"blue\",\"items\": [ {\"color\": \"green\", \"shape\": \"round\" }, { \"color\": \"black\", \"shape\": \"square\" } ] } }, { \"color\": \"yellow\", \"shape\": \"round\" } ] } }";
ObjectMapper mapper = new ObjectMapper();
NestedObject nestedObj = null;
try {
nestedObj = mapper.readValue(json, NestedObject.class);
} catch (JsonParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (JsonMappingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(nestedObj.toString());
}
}
So basically, I have a JSON String that I want to map to the following Java object structure: a Nestedobject class with a Container object that has a list whereby the list can either contain a simple Item with properties color and shape OR a Container object again which has a list with either an Item or a Container and so on.
I hope I described my problem clearly enough and someone can help me on this.