On Thu, Sep 12, 2019 at 11:27 AM Marc Dzaebel <[email protected]> wrote:
>
> Hi,
>
> I defined a mapper that serializes Exception's polymorphically, but the
> following simple map serializes without @class attribute in its values:
>
> Map<Integer, Exception> map = new HashMap<>();
> map.put(1, new Exception("test"));
> mapper.writeValueAsString(map) --> {"1":{"stackTrace":[...], ...}} //
> missing @class
>
> while e.g. Exception is serialized correctly:
>
> mapper.writeValueAsString(new Exception("test")) -->
> {"@class":"java.lang.Exception", "stackTrace":[...], ...}
>
> Is this intended or is there a setting, that enables transitive polymorphic
> serialisation in Map values? May be I have to write serializers/deserializers?
This is bit of a FAQ, but the problem is Java Type Erasure: attempts
to serialize values of generic types as root values is problematic as
there is no generic runtime type available: all Jackson sees is a
`Map<?, ?>` (unlike with properties, where generic type is retained in
class file).
Because of this, I personally recommend not using root values that are
of generic type, and instead always use a Bean class as root value,
even if as simple wrapper around Map or List:
public class Response {
public Map<Integer, Exception> exceptions;
}
since `Response` is not generic, and it all will work fine.
There are 2 workarounds:
1. Use a non-generic helper type:
public class IntExceptionMap extends HashMap<Integer, Exception> { }
in this case full generic type info IS available (due to sub-classing)
2. Force type on serialization
String json = mapper.writerFor(new TypeReference<Map<Integer,
Exception>>() { })
.writeValueAsString(map)
I hope this helps,
-+ Tatu +-
--
You received this message because you are subscribed to the Google Groups
"jackson-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/jackson-user/CAL4a10jSB5u3tZScw26TrEaEDW1M0-UqbD%2Brb4yUEPP9XkQWpg%40mail.gmail.com.