问题
So I've been trying to get Jackson to serialize/deserialize one object I have which is esentially of the structure:
MyObject {
String a;
Map<String, Object> map;
}
where map can hold nested maps or 'primitive' values (String, Integer, Long, Double...)
Obviously, as the type information is required to correctly deserialize this I've had to tell Jackson to do this - for which I've used default typing:
return new ObjectMapper()
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.enableDefaultTyping(ObjectMapper.DefaultTyping.JAVA_LANG_OBJECT, JsonTypeInfo.As.WRAPPER_ARRAY);
The object ends up serializing exactly how I'd like it to, adding type information only where it is necessary:
{
"a" : "SomeString",
"map" : {
"String1" : "String1",
"Float1" : ["java.lang.Float", 1.0],
"Long1" : ["java.lang.Long", 1],
"Int1" : 1,
"Double1" : 1.0
}
}
However, when I attempt to deserialize this JSON with Jackson, it fails with the following error:
java.lang.IllegalArgumentException: Can not deserialize instance of <my type> out of START_ARRAY token
at [Source: N/A; line: -1, column: -1] (through reference chain: <my type>["name"])
at com.fasterxml.jackson.databind.ObjectMapper._convert(ObjectMapper.java:2615)
at com.fasterxml.jackson.databind.ObjectMapper.convertValue(ObjectMapper.java:2542)
at com.rbsgbm.agile.mongo.dbobject.JacksonDBObjectConverter.fromDBObject(JacksonDBObjectConverter.java:39)
at com.rbsgbm.agile.mongo.DBCursorIterator.next(DBCursorIterator.java:32)
at com.rbsgbm.agile.repository.StorageBasedRepository$StorageBasedQuery$StorageBasedQueryIterator.next(StorageBasedRepository.java:258)
at com.rbsgbm.agile.repository.StorageBasedRepository$StorageBasedQuery$StorageBasedQueryIterator.next(StorageBasedRepository.java:242)
at com.rbs.agile.strategy.strategymanager.store.mongo.MongoStrategyStore.loadStrategies(MongoStrategyStore.java:81)
This would suggest that it is getting confused about the value in the map where Jackson decided no type information is necessary, and thus didn't wrap it in an array.
Could somebody advise on the correct way to do this please?
回答1:
Hi there man please do this to solve your problem
first create a class MyObject with the appropriate getter and setter methods.
/**
*
* @author qualebs
*/
public class MyObject {
private String a;
private Map<String, Object> map;
public String getA() {
return a;
}
public void setA(String a) {
this.a = a;
}
public Map<String, Object> getMap() {
return map;
}
public void setMap(Map<String, Object> map) {
this.map = map;
}
}
then create an instance of your ObjectMapper with the following Configuration in the class where you are serializing MyObject
ObjectMapper mapper = new ObjectMapper().configure(Feature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
// get an create a new MyObject
MyObject object = new MyObject();
// set the values you want ie the String a and the Map
Map<String, Object> map = new HashMap<String, Object>();
map.put("string", "example string");
map.put("int", 1);
map.put("long", 1l);
map.put("double", 2.0);
// we can also put an array
map.put("intArray", new int[]{1, 2, 3, 10});
// add the map to your object
object.setMap(map);
// set the string a
object.setA("example String 2");
// now we serialize the object
String mySerializedObj = mapper.writeValueAsString(object);
// to deserialize simply do
MyObject myUnserializedObj = mapper.readValue(mySerializedObj, MyObject.class);
please if this answers your questions accept my answer i could use the points. thank you.
来源:https://stackoverflow.com/questions/17694042/jackson-default-typing-for-object-containing-a-field-of-mapstring-object