问题
I have been searching all day for something that answers this, but I have not had a lot of luck thus far.
My question is straightforward: how do I deserialize an anonymous object correctly using Jackson.
private interface Interface1
{
int getValue();
}
public static void testAnonymousObject() throws IOException
{
ObjectMapper mapper = new ObjectMapper();
mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
mapper.setVisibility(PropertyAccessor.ALL, Visibility.NONE);
mapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY);
mapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
Interface1 testObject = new Interface1()
{
private final int value = 5;
@Override
public int getValue()
{
return value;
}
};
String json = mapper.writeValueAsString(testObject);
System.out.println("JSON = " + json);
Interface1 received = (Interface1) mapper.readValue(json, Object.class);
System.out.println(received);
}
The output of this is: JSON = ["com.foo.test.JacksonTest$1",{"value":5}] before I get an exception:
Exception in thread "main" com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize Class com.foo.test.JacksonTest$1 (of type local/anonymous) as a Bean.
EDIT Just to clarify, both Jackson and XStream are able to serialize the object. But only XStream seems to be able to deserialize the object back. So this scenario can be made to work.
回答1:
As of the time I am writing this, it seems that Jackson does not serialize inner classes or anonymous classes correctly. Other packages such as XStream and Kryo, do however.
回答2:
Problem is not just about it being an inner class (which may or may not be problematic, depending on whether implementation is static or non-static), but also in that no type information is included -- all Jackson sees is type Interface1. To enable reading it back it is necessary to either include type information ("polymorphic type handling"), or to specify mapping between abstract type and implementation class.
Given that you are using an anonymous inner class, you would be able to support this usage by enabled so-called "default typing" (see ObjectMapper javadocs for enableDefaultTyping() or such).
But you may also need to implement specific strategy, if you do not want to enable type inclusion for all non-final types.
To see whether type id is included you can enable default typing with one of default options and have a look at JSON being produced: there should be an additional type id ("@class" property when class name is used as id).
回答3:
Because inner classes do not have a default zero argument constructor (they have a hidden reference to the outer/parent class) Jackson cannot instantiate them.
you can check this link
来源:https://stackoverflow.com/questions/28418564/jackson-deserialization-with-anonymous-classes